Previous answers
The answer to a similar question is wrong.
类似问题的答案是错误的。
Method calls are mentionned neither in Ruby documentation nor in the community wiki.
在Ruby文档和社区维基中都没有提到方法调用。
Method call without parentheses
Higher than or
or
seems to have a lower precedence than a method call without parentheses :
或者似乎比没有括号的方法调用具有更低的优先级:
puts false or true
is equivalent to
相当于
( puts false ) or true
and displays false
.
并显示错误。
NOTE: I know or
shouldn't be used. Still, it's a good example to show that some operators do have lower precedence than method calls.
注意:我知道或不应该使用。不过,这是一个很好的例子,表明某些运算符的优先级低于方法调用。
Lower than ||
puts false || true
is equivalent to
相当于
puts (false || true)
and displays true
.
并显示真实。
Method call with parentheses
The parentheses used for method call don't seem to be grouping :
用于方法调用的括号似乎不是分组:
puts(false or true)
# SyntaxError: unexpected keyword_or
puts((false or true))
#=> true
Question
Where should method calls with and without parentheses be in this precedence table?
带括号和不带括号的方法调用应该放在这个优先级表中的哪个位置?
Bounty clarification
I'm looking for the exact location of method calls in the table. Preferably with examples proving it's lower than the previous one and higher than the next one.
我正在寻找表中方法调用的确切位置。优选地,通过示例证明它低于前一个并且高于下一个。
The current answers also don't seem to mention method calls with parentheses.
目前的答案似乎也没有提到带括号的方法调用。
Thanks in advance!
提前致谢!
3 个解决方案
#1
6
Prelude
This aims to test all possible scenarios.
这旨在测试所有可能的情况。
Note that when saying "operator X
has higher precedence than method invocation" what is meant is in arguments. Aka:
注意,当说“运算符X具有比方法调用更高的优先级”时,意味着在参数中。又名:
invocation foo X bar
as opposed to (call on object)
而不是(呼吁对象)
X invocation
As far as the second case is concerned, method calls always have higher precedence.
就第二种情况而言,方法调用始终具有更高的优先级。
Short answer
It doesn't fit:
它不适合:
- It causes
SyntaxError
in some cases - It has higher precedence than
rescue
, but lower than assignment
在某些情况下会导致SyntaxError
它具有比救援更高的优先级,但低于分配
Summary
-
not
can't be used after method invocation regardless of brackets - Using brackets (
()
) with method invocations sometimes causes aSyntaxError
. These cases are:and
,or
,if
,unless
,until
,while
andrescue
- In cases when brackets don't cause an error, they don't change the precedence in any way
- All operators, except for
and
,or
, postfixif
,unless
,until
,while
,rescue
have higher precedence than method invocation
无论括号如何,都不能在方法调用后使用
在方法调用中使用方括号(())有时会导致语法错误。这些案件是:和,或者,如果,除非,直到,同时和救援
如果括号不会导致错误,则它们不会以任何方式更改优先级
所有运算符,除了和,或后缀if,除非,直到,while,具有比方法调用更高的优先级
Lets try it:
让我们尝试一下:
class Noone < BasicObject
undef_method :!
def initialize(order)
@order = order
end
def method_missing(name, *args)
@order << name
self
end
end
First unary:
# + and - will become binary
unary_operators = %i(! ~ not defined?)
puts 'No brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta #{operator} bar")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
puts 'Brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta(#{operator} bar)")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
Points taken:
-
not
after a method invocation is aSyntaxError
- all unary operators have higher precedence than method invocation regardless of brackets
不是在方法调用之后是SyntaxError
无论括号如何,所有一元运算符的优先级都高于方法调用
Now binary:
binary_operators = %i(
**
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === =~
.. ...
or and
)
puts 'No brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta bar #{operator} baz")
rescue SyntaxError => e
puts e
end
p order
end
puts 'Brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta( bar #{operator} baz)")
rescue SyntaxError => e
puts e
end
p order
end
Points taken:
- brackets around method invocation with
and
oror
is aSyntaxError
- we have to test
and
andor
further without brackets -
..
and...
call<=>
. We have to test this further - we couldn't test a few other binary operators this way, namely
&&
,||
,==
,!=
, modifierrescue
,if
,unless
,until
,while
- other than the above mentioned, operators have higher precedence, regardless of brackets
方法调用周围的括号使用和或或是一个SyntaxError
我们必须测试和/或进一步没有括号
..和...打电话<=>。我们必须进一步测试
我们无法用这种方式测试其他一些二元运算符,即&&,||,==,!=,modifier rescue,if,除非,直到,而
除了上面提到的,运营商具有更高的优先权,无论括号如何
def yes
puts 'yes'
true
end
def no
puts 'no'
false
end
def anything(arg)
puts 'Anything'
arg
end
anything yes and no
anything no or yes
anything yes && no
anything no || yes
anything(yes && no)
anything(no || yes)
anything yes == no
anything(yes == no)
anything yes != no
anything(yes != no)
Points taken:
-
and
andor
have lower precedence without brackets -
&&
,||
,==
and!=
have higher precedence regardless of brackets
和和或没有括号的优先级较低
&&,||,==和!=无论括号如何都具有更高的优先级
def five(*args)
p args
5
end
five 2..7
five(2..7)
five 2...7
five(2...7)
Points taken:
-
..
and...
have higher precedence regardless of brackets
..和......无论括号如何都有更高的优先级
anything yes if no
anything(yes if no)
anything no unless yes
anything(no unless yes)
anything no until yes
anything(no until yes)
anything yes while no
anything(yes while no)
Points taken:
- brackets with
if
,unless
,until
,while
cause aSyntaxError
- all of the above have lower precedence than method invocation without brackets
括号if,除非,until,while导致SyntaxError
所有上面的优先级都低于没有括号的方法调用
def error
puts 'Error'
raise
end
anything error rescue yes
anything(error rescue yes)
Points taken:
- brackets around
rescue
cause aSyntaxError
-
rescue
has lower precedence if no brackets are present
救援周围的括号导致SyntaxError
如果不存在括号,则救援优先级较低
Ternary:
anything yes ? no : 42
anything(yes ? no : 42)
Points taken:
- ternary has higher precedence regardless of brackets
无论括号如何,三元都有更高的优先级
Assignment (left for last as it changes yes
and no
):
分配(留为最后,因为它改变是和否):
anything yes = no
anything(no = five(42))
Points taken:
- Assignment has higher precedence than invocation
赋值具有比调用更高的优先级
Note that +=
and the like are just shortcuts for +
and =
so they exhibit the same behaviour.
请注意,+ =等只是+和=的快捷方式,因此它们表现出相同的行为。
#2
2
In Ruby, method call precedence seems to be lower than defined?
but higher than or
.
在Ruby中,方法调用优先级似乎低于定义的?但高于或。
For example:
puts defined? true
#=> true
puts false or true
#=> prints `false` and returns `true`
Note: puts(not true)
and puts(false or true)
raise syntax errors.
注意:puts(不是true)和puts(false或true)会引发语法错误。
#3
2
Updating to actually answer the question.
更新以实际回答问题。
Officially methods don't have a precedence. However as you demonstrate we can sort them into the precedence list and they fall between what we could consider "operators" and what we could consider "control flow" keywords.
官方方法没有优先权。然而,正如您所展示的那样,我们可以将它们排序到优先级列表中,它们介于我们可以考虑的“运算符”和我们可以考虑的“控制流”关键字之间。
See, https://ruby-doc.org/core-2.2.0/doc/syntax/precedence_rdoc.html
Which starts with operators, and ends with control-flow constructs like
它从运算符开始,以控制流结构为结束
?, :
modifier-rescue
=, +=, -=, etc.
defined?
not
or, and
modifier-if, modifier-unless, modifier-while, modifier-until
The only oddball there is defined?
of which I don't understand why it hasn't been defined as a global function on the Kernel
module anyway.
那个唯一的古怪定义了吗?其中我不明白为什么它还没有被定义为内核模块的全局函数。
Missing raise
, loop
, catch/throw
and others?
缺少加注,循环,捕获/抛出等等?
They are not keywords but method calls that are defined as module_function
on the Kernel
module. And since this module is included in Object
they are made into private methods of all classes and thus appear to be global functions that are available everywhere.
它们不是关键字,而是在内核模块上定义为module_function的方法调用。由于这个模块包含在Object中,因此它们被制作成所有类的私有方法,因此看起来是遍布各处的全局函数。
Hope that helps to answer the question. Sorry for the original copypasta.
希望有助于回答这个问题。抱歉原始的copypasta。
#1
6
Prelude
This aims to test all possible scenarios.
这旨在测试所有可能的情况。
Note that when saying "operator X
has higher precedence than method invocation" what is meant is in arguments. Aka:
注意,当说“运算符X具有比方法调用更高的优先级”时,意味着在参数中。又名:
invocation foo X bar
as opposed to (call on object)
而不是(呼吁对象)
X invocation
As far as the second case is concerned, method calls always have higher precedence.
就第二种情况而言,方法调用始终具有更高的优先级。
Short answer
It doesn't fit:
它不适合:
- It causes
SyntaxError
in some cases - It has higher precedence than
rescue
, but lower than assignment
在某些情况下会导致SyntaxError
它具有比救援更高的优先级,但低于分配
Summary
-
not
can't be used after method invocation regardless of brackets - Using brackets (
()
) with method invocations sometimes causes aSyntaxError
. These cases are:and
,or
,if
,unless
,until
,while
andrescue
- In cases when brackets don't cause an error, they don't change the precedence in any way
- All operators, except for
and
,or
, postfixif
,unless
,until
,while
,rescue
have higher precedence than method invocation
无论括号如何,都不能在方法调用后使用
在方法调用中使用方括号(())有时会导致语法错误。这些案件是:和,或者,如果,除非,直到,同时和救援
如果括号不会导致错误,则它们不会以任何方式更改优先级
所有运算符,除了和,或后缀if,除非,直到,while,具有比方法调用更高的优先级
Lets try it:
让我们尝试一下:
class Noone < BasicObject
undef_method :!
def initialize(order)
@order = order
end
def method_missing(name, *args)
@order << name
self
end
end
First unary:
# + and - will become binary
unary_operators = %i(! ~ not defined?)
puts 'No brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta #{operator} bar")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
puts 'Brackets'
unary_operators.each do |operator|
puts operator
order = []
foo = Noone.new order
bar = Noone.new order
begin
eval("foo.meta(#{operator} bar)")
rescue SyntaxError => e
puts e
end
p order
puts '-----------'
end
Points taken:
-
not
after a method invocation is aSyntaxError
- all unary operators have higher precedence than method invocation regardless of brackets
不是在方法调用之后是SyntaxError
无论括号如何,所有一元运算符的优先级都高于方法调用
Now binary:
binary_operators = %i(
**
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === =~
.. ...
or and
)
puts 'No brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta bar #{operator} baz")
rescue SyntaxError => e
puts e
end
p order
end
puts 'Brackets'
binary_operators.each do |operator|
order = []
foo = Noone.new order
bar = Noone.new order
baz = Noone.new order
begin
eval("foo.meta( bar #{operator} baz)")
rescue SyntaxError => e
puts e
end
p order
end
Points taken:
- brackets around method invocation with
and
oror
is aSyntaxError
- we have to test
and
andor
further without brackets -
..
and...
call<=>
. We have to test this further - we couldn't test a few other binary operators this way, namely
&&
,||
,==
,!=
, modifierrescue
,if
,unless
,until
,while
- other than the above mentioned, operators have higher precedence, regardless of brackets
方法调用周围的括号使用和或或是一个SyntaxError
我们必须测试和/或进一步没有括号
..和...打电话<=>。我们必须进一步测试
我们无法用这种方式测试其他一些二元运算符,即&&,||,==,!=,modifier rescue,if,除非,直到,而
除了上面提到的,运营商具有更高的优先权,无论括号如何
def yes
puts 'yes'
true
end
def no
puts 'no'
false
end
def anything(arg)
puts 'Anything'
arg
end
anything yes and no
anything no or yes
anything yes && no
anything no || yes
anything(yes && no)
anything(no || yes)
anything yes == no
anything(yes == no)
anything yes != no
anything(yes != no)
Points taken:
-
and
andor
have lower precedence without brackets -
&&
,||
,==
and!=
have higher precedence regardless of brackets
和和或没有括号的优先级较低
&&,||,==和!=无论括号如何都具有更高的优先级
def five(*args)
p args
5
end
five 2..7
five(2..7)
five 2...7
five(2...7)
Points taken:
-
..
and...
have higher precedence regardless of brackets
..和......无论括号如何都有更高的优先级
anything yes if no
anything(yes if no)
anything no unless yes
anything(no unless yes)
anything no until yes
anything(no until yes)
anything yes while no
anything(yes while no)
Points taken:
- brackets with
if
,unless
,until
,while
cause aSyntaxError
- all of the above have lower precedence than method invocation without brackets
括号if,除非,until,while导致SyntaxError
所有上面的优先级都低于没有括号的方法调用
def error
puts 'Error'
raise
end
anything error rescue yes
anything(error rescue yes)
Points taken:
- brackets around
rescue
cause aSyntaxError
-
rescue
has lower precedence if no brackets are present
救援周围的括号导致SyntaxError
如果不存在括号,则救援优先级较低
Ternary:
anything yes ? no : 42
anything(yes ? no : 42)
Points taken:
- ternary has higher precedence regardless of brackets
无论括号如何,三元都有更高的优先级
Assignment (left for last as it changes yes
and no
):
分配(留为最后,因为它改变是和否):
anything yes = no
anything(no = five(42))
Points taken:
- Assignment has higher precedence than invocation
赋值具有比调用更高的优先级
Note that +=
and the like are just shortcuts for +
and =
so they exhibit the same behaviour.
请注意,+ =等只是+和=的快捷方式,因此它们表现出相同的行为。
#2
2
In Ruby, method call precedence seems to be lower than defined?
but higher than or
.
在Ruby中,方法调用优先级似乎低于定义的?但高于或。
For example:
puts defined? true
#=> true
puts false or true
#=> prints `false` and returns `true`
Note: puts(not true)
and puts(false or true)
raise syntax errors.
注意:puts(不是true)和puts(false或true)会引发语法错误。
#3
2
Updating to actually answer the question.
更新以实际回答问题。
Officially methods don't have a precedence. However as you demonstrate we can sort them into the precedence list and they fall between what we could consider "operators" and what we could consider "control flow" keywords.
官方方法没有优先权。然而,正如您所展示的那样,我们可以将它们排序到优先级列表中,它们介于我们可以考虑的“运算符”和我们可以考虑的“控制流”关键字之间。
See, https://ruby-doc.org/core-2.2.0/doc/syntax/precedence_rdoc.html
Which starts with operators, and ends with control-flow constructs like
它从运算符开始,以控制流结构为结束
?, :
modifier-rescue
=, +=, -=, etc.
defined?
not
or, and
modifier-if, modifier-unless, modifier-while, modifier-until
The only oddball there is defined?
of which I don't understand why it hasn't been defined as a global function on the Kernel
module anyway.
那个唯一的古怪定义了吗?其中我不明白为什么它还没有被定义为内核模块的全局函数。
Missing raise
, loop
, catch/throw
and others?
缺少加注,循环,捕获/抛出等等?
They are not keywords but method calls that are defined as module_function
on the Kernel
module. And since this module is included in Object
they are made into private methods of all classes and thus appear to be global functions that are available everywhere.
它们不是关键字,而是在内核模块上定义为module_function的方法调用。由于这个模块包含在Object中,因此它们被制作成所有类的私有方法,因此看起来是遍布各处的全局函数。
Hope that helps to answer the question. Sorry for the original copypasta.
希望有助于回答这个问题。抱歉原始的copypasta。