Ruby方法调用的优先级是什么?

5
http://phrogz.net/programmingruby/language.html#table_18.4提供的表格只显示了Ruby运算符的优先级。那么方法(或者说:消息/函数)的优先级是什么呢?
例如,在irb中输入以下内容:
Math.sqrt 2 + 2

我得到了2.0作为结果。没有确定的优先级规则,我就不能决定在哪里使用圆括号,在哪里省略它们。因此,有人请帮助我消除这种不确定性。谢谢!

4个回答

4
任何运算符都比方法调用的优先级高。 强烈建议使用 () 来进行方法调用,以避免出现您所询问的情况。

4
任何一种运算符都比方法调用的优先级高这句话是错误的。例如,puts false or true 会显示 false,而 puts false || true 则会显示 true - Eric Duminil
1
除了 @Eric 的观察之外,一个没有证据支持的断言有什么价值? - Cary Swoveland

2
我们可以以你提供的《Programming Ruby》链接为起点,自行发现未加括号的方法调用在优先级表中的位置。我只会展示最终测试结果,准确定位其所在位置。
它比defined?的优先级低:
defined? Math.sqrt 2
# => SyntaxError: unexpected tINTEGER, expecting end-of-input

啊哈,它比“不”高:
not Math.sqrt 2
=> false

现在你知道应该在什么时候使用括号了。
附注:
(感谢Martin Demello提供的ruby-talk链接,提醒我注意这一点)
请记住,表格中的运算符仅适用于未在方法调用语法中使用的情况。例如,以下示例不遵守*和+的规则,因为它们未被用作运算符,而是方法:
# This happens because unparenthesized method calls are right-associative.
2.* 5.+ 2  # => 14

如果这看起来令人困惑,那么同样的事情也会在这里发生:
# The `modulo` is evaluated first because it's on the right
Math.sqrt 9.modulo 5

2
Ruby方法调用的优先级低于任何运算符,但这并不是全部 - 有一些边缘情况是不明显的。你的问题让我对其中一个产生了好奇心,所以我在ruby-talk邮件列表上提出了这个问题。你应该会发现结果线程很有帮助。
此外,阅读这篇博客文章可以得到一个很好的论点,即你应该在学习Ruby时自由使用括号。点击此处阅读

这可能有点难度,但你是否有那篇博客文章的备用链接?该链接已经失效,我在archive.org和Google上都找不到它。 - Adam Rosenfield
请看这里:http://graysoftinc.com/early-steps/do-i-need-these-parentheses - Martin DeMello

1
在Ruby中,任何运算符都比方法调用具有优先级,例如,首先计算运算符。
但是,Math.sqrt 2 + 2这个示例很好地说明了留出括号会有多难阅读和不直观。人们可能希望在此处评估Math.sqrt(2) + 2
当你遇到这样一行代码时,你可能会想:程序员的意图是什么?这是一个错误吗?
总是在可能的情况下使用括号是一个好习惯,可以清楚地表明你想要的内容,特别是当存在方法调用或多个运算符时 - 这只是一种良好的风格,并且是最低风险的方法(即不要做出假设,而要通过使用括号使自己清晰)。
在表达式中添加额外的括号永远不会有害,但是留出括号可能会有相当大的伤害。
以下是我最近遇到的一个很好的例子:
  def foo(arg)
    raise "error"
  end
  x = foo 4 rescue 7
  x 
    => nil    # oops!

  x = foo(4) rescue 7
  x
    => 7

我希望这清楚地说明了为什么使用括号很重要

另外:

请查看此处,下面的“调用方法”:http://ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html 引用:

[...] 如果没有歧义,当调用方法时可以省略参数列表周围的括号。[...] 但是,在除了最简单的情况之外,我们不推荐这样做 ---有一些微妙的问题可能会绊倒您。[特别是,必须在另一个方法调用的参数上使用括号(除非它是最后一个参数)。]我们的规则很简单:如果有任何疑问,请使用括号。

另请参阅:http://phrogz.net/programmingruby/language.html


2
谷歌是什么?我花了十到十五分钟的时间试图找到一个有用的页面指向OP,但是没有结果。而且过去12年我一直在使用Ruby,所以我对使用什么搜索词有很好的想法。至于Tile的回答,它不仅没有帮助(如果他真的仔细阅读原始问题和/或实际运行查询,他会发现这一点),而且它链接到lmgtfy,如果不是全面钓鱼,就是过分无礼。 - Martin DeMello
为什么有些人总是对事情表现得那么恶劣呢?仅仅因为答案已经存在,这并不意味着每个人都能以相同的水平去阅读和理解它。 - killerbarney
我希望这能澄清答案。 - Tilo
这实际上是错误的,Math.sqrt 2 + 2 被解释为 Math.sqrt(2 + 2)。而且我非常怀疑省略括号是因为“懒惰”的结果。你也没有真正回答问题,而是通过简单地说要始终使用括号来回避它。 - Andrew Marshall
-1 是因为 Ruby 中间的内容不准确(编辑:至少在 1.9.3 版本中如此)。就像注释所说的那样,如果 &&|| 具有相同的优先级,我希望第一个语句从左到右进行计算,即 (true || true) && false,结果为 false。而且第二个语句表明 true || (true && false)false,但实际上它是 true - nickgrim
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接