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

标签 ruby methods operator-precedence

以前的答案

answer类似question是错误的。

Ruby 中均未提及方法调用 documentation也不在 community wiki .

不带括号的方法调用

高于

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

puts false or true

相当于

( puts false ) or true

并显示false

注意:我知道不应该使用 or。尽管如此,这仍然是一个很好的例子,表明某些运算符的优先级确实低于方法调用。

低于||

puts false || true

相当于

puts (false || true)

并显示 true

带括号的方法调用

用于方法调用的括号don't seem进行分组:

puts(false or true)
# SyntaxError: unexpected keyword_or
puts((false or true))
#=> true

问题

带括号和不带括号的方法调用应该在这个优先级中的什么位置 table

赏金说明

我正在查找表中方法调用的确切位置。最好有例子证明它比前一个低,比下一个高。

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

提前致谢!

最佳答案

前奏

这旨在测试所有可能的场景。

请注意,当说“运算符X 比方法调用具有更高的优先级” 时,意思是在参数中。又名:

invocation foo X bar

相对于(调用对象)

X invocation

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


简答

不合适:

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

总结

  • not无论括号如何,都不能在方法调用后使用
  • 在方法调用中使用方括号 ( ()) 有时会导致 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

第一个一元:

# + 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

取得的分数:

  • 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

取得的分数:

  • 括号内的方法调用 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)

取得的分数:

  • andor没有括号的优先级较低
  • && , || , ==!=无论括号如何,都具有更高的优先级

def five(*args)
  p args
  5
end

five 2..7
five(2..7)
five 2...7
five(2...7)

取得的分数:

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

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)

取得的分数:

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

def error
  puts 'Error'
  raise
end

anything error rescue yes
anything(error rescue yes)

取得的分数:

  • 括号rescue导致SyntaxError
  • rescue如果没有括号,则优先级较低

三元:

anything yes ? no : 42
anything(yes ? no : 42)

取得的分数:

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

赋值(留到最后,因为它更改了 yesno ):

anything yes = no
anything(no = five(42))

取得的分数:

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

请注意 +=等等只是+的快捷方式和 =所以他们表现出相同的行为。

关于ruby - 带括号和不带括号的方法调用的优先级是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41313154/

相关文章:

haskell - 如何在 GHCI 中发现函数的优先级和关联性?

java - 在这种方法调用和传入参数的情况下,是否保证 Java 评估顺序

ruby-on-rails - Ruby/Rails 中的类方法与常量

ruby - `build' : undefined method `new' for ExceptionNotifier:Module (NoMethodError) when executing rails s

c++ - 为什么你会想要创建一个名为 *foo() 而不仅仅是 foo() 的方法?

c++ - 'for' 循环内的后增量和预增量产生相同的输出

ruby-on-rails - 禁用第一个 nil 选项 - rails

ruby-on-rails - 动态属性列表 rabl

java - 如何在同一个java项目中调用不同类的另一个方法

c# - 这是使用泛型方法的好方法吗?