4

我刚刚遇到了一个问题,即函数返回的值取决于我是否对该结果调用 puts。我想知道这是可以预期的,还是某种解析器错误。

这仅在传递给函数的块使用do...end语法而不是内联{...}语法时才会发生。这是一个例子:

arr = ["a", "b", "c"]
puts i = arr.index { |x| == "b" }
#=> 1

正如预期的那样,但这并不像我预期的那样工作:

arr = ["a", "b", "c"]
puts i = arr.index do |x|
  x == "b"
end
#=> #<Enumerator:0xSomeId>

虽然如果我这样做效果很好:

arr = ["a", "b", "c"]
i = arr.index do |x|
  x == "b"
end
puts i
#=> 1

看起来它被解释为好像根本没有传递任何块(返回枚举器是arr.index使用块调用的预期行为)。这是正常的吗?这种行为是否在任何地方进行了解释/记录?

4

2 回答 2

7

do...end{...}由于优先级,块与最左边的方法相关联,而块与最右边的方法相关联。在您的第二个示例中,该块与 关联puts,这与它无关。

在这种情况下,这似乎是一种奇怪的行为,但正是do...end块的这一特性为许多 Ruby DSL提供了干净、可读的语法。

于 2012-08-20T01:03:53.090 回答
2

{ ... }比 绑定得更紧密do ... end,因此您的do ... end块最终会附加到IO#puts(忽略它)而不是Array#index.

如果你把 then parens 放入puts() call你可以看到:

puts(i = arr.index do |x| x == 'b' end)
于 2012-08-20T02:30:32.300 回答