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

时间:2016-12-24 12:13:13

标签: ruby methods operator-precedence

以前的答案

类似answerquestion是错误的。

方法调用既不在Ruby documentation中也不在community wiki中提及。

没有括号的方法调用

高于or

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

赏金澄清

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

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

提前致谢!

3 个答案:

答案 0 :(得分:7)

前奏

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

注意,当说"运算符X的优先级高于方法调用时," 的含义是参数。又名:

invocation foo X bar

而不是(调用对象)

X invocation

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

简短回答

它不合适:

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

摘要

    无论括号,都不能在方法调用之后使用
  • not
  • 对方法调用使用括号(())有时会导致SyntaxError。这些案例包括:andorifunlessuntilwhilerescue
  • 如果括号不会导致错误,则不会以任何方式更改优先顺序
  • 所有运营商,andor,后缀ifunlessuntilwhilerescue除外优先级高于方法调用

让我们尝试一下:

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

积分:

    方法调用后的
  • notSyntaxError
  • 所有一元运算符的优先级高于方法调用,而不管括号

现在二元:

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

积分:

    使用andor进行方法调用的
  • 括号为SyntaxError
  • 我们必须进一步测试andor无括号
  • .....致电<=>。我们必须进一步测试
  • 我们无法通过这种方式测试其他一些二元运算符,即&&||==!=,修饰符rescueifunlessuntilwhile
  • 除了上面提到的,运营商具有更高的优先级,无论括号
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)

积分:

  • 括号ifunlessuntilwhile会导致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))

积分:

  • 分配的优先级高于调用

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

答案 1 :(得分:2)

在Ruby中,方法调用优先级似乎低于defined?但高于or

例如:

puts defined? true
#=> true

puts false or true
#=> prints `false` and returns `true`

注意: puts(not true)puts(false or true)会引发语法错误。

答案 2 :(得分:2)

更新以实际回答问题。

官方方法没有优先权。然而,正如您所展示的那样,我们可以将它们排序到优先级列表中,它们介于我们可以考虑的范围之间&#34;运算符&#34;我们可以考虑什么&#34;控制流程&#34;关键字。

请参阅https://ruby-doc.org/core-2.2.0/doc/syntax/precedence_rdoc.html

以操作符开头,以

之类的控制流结构结束
?, :
modifier-rescue
=, +=, -=, etc.
defined?
not
or, and
modifier-if, modifier-unless, modifier-while, modifier-until

唯一奇怪的是defined?其中我不明白为什么它还没有被定义为Kernel模块的全局函数。

缺少raiseloopcatch/throw和其他人?

它们不是关键字,而是在module_function模块上定义为Kernel的方法调用。由于这个模块包含在Object中,因此它们被制作成所有类的私有方法,因此看起来是可在任何地方使用的全局函数。

希望有助于回答这个问题。抱歉原始的copypasta。