使用括号和不使用括号的方法调用的优先级是什么?

Eri*_*nil 9 ruby methods operator-precedence

以前的答案

回答一个类似的问题是错误的.

在Ruby 文档社区维基中都没有提到方法调用.

没有括号的方法调用

比......高 or

or 似乎优先级低于没有括号的方法调用:

puts false or true
Run Code Online (Sandbox Code Playgroud)

相当于

( puts false ) or true
Run Code Online (Sandbox Code Playgroud)

和显示false.

注意:我知道or不应该使用.不过,这是一个很好的例子,表明某些运算符的优先级低于方法调用.

低于 ||

puts false || true
Run Code Online (Sandbox Code Playgroud)

相当于

puts (false || true)
Run Code Online (Sandbox Code Playgroud)

和显示true.

用括号调用方法

用于方法调用的括号似乎不是分组:

puts(false or true)
# SyntaxError: unexpected keyword_or
puts((false or true))
#=> true
Run Code Online (Sandbox Code Playgroud)

带括号和不带括号的方法调用应该在这个优先级表中的哪个位置?

赏金澄清

我正在寻找表中方法调用的确切位置.优选地,通过示例证明它低于前一个并且高于下一个.

目前的答案似乎也没有提到带括号的方法调用.

提前致谢!

ndn*_*kov 7

序幕

这旨在测试所有可能的情况.

请注意,当说"运算符X具有比方法调用更高的优先级"时,意味着在参数中.又名:

invocation foo X bar
Run Code Online (Sandbox Code Playgroud)

而不是(呼吁对象)

X invocation
Run Code Online (Sandbox Code Playgroud)

就第二种情况而言,方法调用总是具有更高的优先级.


简短的回答

它不适合:

  • SyntaxError在某些情况下会导致
  • 它具有rescue比赋值更高的优先级,但低于赋值

摘要

  • not 无论括号如何,都不能在方法调用之后使用
  • 使用()带有方法调用的方括号()有时会导致a SyntaxError.这些案件是:and,or,if,unless,until,whilerescue
  • 如果括号不会导致错误,则它们不会以任何方式更改优先级
  • 所有的运营商,除了and,or,后缀if,unless,until,while,rescue比方法调用更高的优先级

让我们尝试一下:

class Noone < BasicObject
  undef_method :!

  def initialize(order)
    @order = order
  end

  def method_missing(name, *args)
    @order << name
    self
  end
end
Run Code Online (Sandbox Code Playgroud)

第一个一元:

# + 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
Run Code Online (Sandbox Code Playgroud)

积分:

  • not 在方法调用之后是一个 SyntaxError
  • 无论括号如何,所有一元运算符的优先级都高于方法调用

现在二进制:

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
Run Code Online (Sandbox Code Playgroud)

积分:

  • 围绕方法调用括号用andorSyntaxError
  • 我们必须测试andor进一步没有括号
  • .....打电话<=>.我们必须进一步测试
  • 我们无法测试其他一些二元运算符这种方式,即&&,||,==,!=,改性剂rescue,if,unless,until,while
  • 除了上面提到的,运营商具有更高的优先权,无论括号如何

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)
Run Code Online (Sandbox Code Playgroud)

积分:

  • and并且or没有括号的优先级较低
  • &&,||,==!=具有较高的优先级,无论支架

def five(*args)
  p args
  5
end

five 2..7
five(2..7)
five 2...7
five(2...7)
Run Code Online (Sandbox Code Playgroud)

积分:

  • ..并且...无论括号如何都具有更高的优先级

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)
Run Code Online (Sandbox Code Playgroud)

积分:

  • 与支架if,unless,until,while导致SyntaxError
  • 所有上面的优先级都低于没有括号的方法调用

def error
  puts 'Error'
  raise
end

anything error rescue yes
anything(error rescue yes)
Run Code Online (Sandbox Code Playgroud)

积分:

  • 括号左右rescue导致aSyntaxError
  • rescue 如果不存在括号,则优先级较低

三元:

anything yes ? no : 42
anything(yes ? no : 42)
Run Code Online (Sandbox Code Playgroud)

积分:

  • 无论括号如何,三元都有更高的优先级

分配(留至最后,因为它的变化yesno):

anything yes = no
anything(no = five(42))
Run Code Online (Sandbox Code Playgroud)

积分:

  • 赋值具有比调用更高的优先级

请注意,+=等等只是快捷方式+,=因此它们表现出相同的行为.