在表达式上调用'puts',改变其解释方式?



我刚刚遇到了一个问题,即函数返回的值根据我是否对该结果调用 put 而有所不同。 我想知道这是否是预期的,或者某种解析器错误。

仅当传递给函数的块使用 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

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

由于

优先级do...end块与最左侧的方法相关联,而{...}块与最右侧的方法相关联。在第二个示例中,块与 puts 相关联,而 对它没有任何作用。

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

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

如果你把括号放到puts() call你可以看到:

puts(i = arr.index do |x| x == 'b' end)

最新更新