1

This expression:

pp [1, 2, 3].map { |r| r+1 }

evaluates to:

[2, 3, 4]
=> [2, 3, 4]

As expected. However, this expression:

pp [1, 2, 3].map do |r|
  r+1
end

evaluates to:

#<Enumerator: ...>
=> #<Enumerator: [1, 2, 3]:map>

Why does pp see an enumerator in the second case, rather than the mapped array?

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
A Fader Darkly
  • 3,516
  • 1
  • 22
  • 28
  • 3
    This is a duplicate of [Ruby Block Syntax Error](http://StackOverflow.Com/q/6854283/2988), [Code block passed to `each` works with brackets but not with `do`-`end` (ruby)](http://StackOverflow.Com/q/6718340/2988), [Block definition - difference between braces and `do`-`end` ?](http://StackOverflow.Com/q/6179442/2988), [Ruby multiline block without `do` `end`](http://StackOverflow.Com/q/3680097/2988), [Using `do` block vs brackets `{}`](http://StackOverflow.Com/q/2122380/2988), [What is the difference or value of these block coding styles in Ruby?](http://StackOverflow.Com/q/533008/2988), … – Jörg W Mittag Sep 07 '18 at 15:19
  • 3
    … [Ruby block and unparenthesized arguments](http://StackOverflow.Com/q/420147/2988), [Why aren't `do`/`end` and `{}` always equivalent?](http://StackOverflow.Com/q/7487664/2988), [Wierd imperfection in Ruby blocks](http://StackOverflow.Com/q/7620804/2988), [Passing block into a method - Ruby](http://StackOverflow.Com/q/10909496/2988), [`instance_eval` block not supplied?](http://StackOverflow.Com/q/12175788/2988), [block syntax difference causes “`LocalJumpError: no block given (yield)`”](http://StackOverflow.Com/q/18623447/2988), … – Jörg W Mittag Sep 07 '18 at 15:19
  • 3
    … [`instance_eval` does not work with `do`/`end` block, only with `{}`-blocks](http://StackOverflow.Com/q/21042867/2988), [`Proc` throws error when used with `do` `end`](http://StackOverflow.Com/q/25217274/2988), [Block not called in Ruby](http://StackOverflow.Com/q/29454056/2988), and [Different behaviour of “`do … end`” and “`{ … }`” block in ruby](http://StackOverflow.Com/q/37638152/2988). – Jörg W Mittag Sep 07 '18 at 15:19

1 Answers1

1

Precedence matters. {} has a higher precedence over method call. do-end has a lower precedence.

pp [1, 2, 3].map { |r| r + 1 }

is parsed as pp ([1, 2, 3].map { |r| r + 1 }), which is:

pp([1, 2, 3].map { |r| r + 1 })

pp [1, 2, 3].map do |r| r + 1 end

is parsed as (pp [1, 2, 3].map) do |r| r + 1 end, which is:

pp([1, 2, 3].map, &->(r){ r + 1 })

In the latter case passing block to pp is a NOOP.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160