I just ran into an issue where the value returned by a function is different depending on whether or not I call puts on that result. I’m wondering if this is to be expected, or some sort of parser error.
This only occurs if the block passed to the function uses the do...end syntax, not the inline {...} syntax. Here’s an example:
arr = ["a", "b", "c"]
puts i = arr.index { |x| == "b" }
#=> 1
as expected, but this does not work as I’d expect:
arr = ["a", "b", "c"]
puts i = arr.index do |x|
x == "b"
end
#=> #<Enumerator:0xSomeId>
Though it works fine if I do:
arr = ["a", "b", "c"]
i = arr.index do |x|
x == "b"
end
puts i
#=> 1
It looks like it’s interpreted as if it were passed no block at all (returning the enumerator is the expected behavior of calling arr.index with block). Is this normal? Is this behavior explained/documented anywhere?
do...endblocks associate with the leftmost method while{...}blocks associate with the rightmost, due to precedence. In your second example, the block is being associated withputs, which does nothing with it.It seems like weird behavior in this case, but it’s this feature of
do...endblocks that give a lot of Ruby DSL‘s their clean, readable syntax.