【问题标题】:Operator Precedence and Order of Evaluation in Ruby: yield vs << (shovel operator)Ruby 中的运算符优先级和求值顺序:yield vs <<(铲子运算符)
【发布时间】:2021-04-16 00:44:21
【问题描述】:

我正在阅读这本书 Well-Grounded Rubyist,其第 184 页的控制流技术章节有一个使用迭代器实现映射的简单示例:

class Array
  def my_map
    c=0
    acc = []
    until c == size
      acc << yield self[c]
      c += 1 end
    acc
  end
end

运行此代码ruby MY_FILE.rb时出现以下错误:

MY_FILE.rb:6: syntax error, unexpected `self', expecting `end'
      acc << yield self[c]

解决这个问题的方法是在yield self[c] 周围加上括号,所以整行看起来像这样:

  acc << (yield self[c])

然后,例程会处理这一行更改。据我了解,问题出在运算符优先级或评估顺序上。我在网上冲浪了很长一段时间,但无法确定为什么书中的代码不起作用。

为什么书籍示例不起作用? acc &lt;&lt; yield self[c] 中的运算符优先级或/和求值顺序是什么?

【问题讨论】:

  • 您也可以使用acc &lt;&lt; yield(self[c]) 我不确定确切原因,但有时需要括号来消除参数歧义
  • 仅供参考,acc &lt;&lt; foo bar 出现相同的语法错误 - 它并非特定于 yield
  • “据我了解,问题出在运算符优先级或评估顺序上。” – 这不可能是评估顺序的问题,因为你得到了一个SyntaxError,因此没有任何东西可能以错误的顺序被评估,因为根本没有任何东西被评估。

标签: ruby iterator operator-precedence yield order-of-execution


【解决方案1】:

通常,方法参数放在括号中:

x=foo(y)
a=bar(baz(z))
b=7+baz(w)

在某些情况下(即如果优先级不绑定其他情况),您可以省略大括号。因此,

x = foo y

有效,但是

a = bar baz z

被解释为

a = (bar(baz))(z)

b = 7 + baz w

作为

b = (7+baz) w

如果对表达式的解释导致有意义的事情,这是有风险的。在这种情况下,您甚至不会收到错误消息,但程序会以与您预期不同的方式运行。

一般来说,在调用方法时始终使用括号是个好主意。

【讨论】:

    猜你喜欢
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2011-06-21
    • 2020-03-05
    相关资源
    最近更新 更多