10

I extracted simple example:

require 'pp'
x = 1..3
pp x.map do |i| {:value => i, :double => (i*2)} end
pp x.map { |i| {:value => i, :double => (i*2)} }

pp(x.map do |i| {:value => i, :double => (i*2)} end)
pp(x.map { |i| {:value => i, :double => (i*2)} })

I am wondering why first pp produces:

[1, 2, 3]

While all the oders are giving:

[{:value=>1, :double=>2}, {:value=>2, :double=>4}, {:value=>3, :double=>6}]

I assume it has something to do with operator precedence. Where can I find good explanation?

niton
  • 8,771
  • 21
  • 32
  • 52
rkj
  • 8,787
  • 2
  • 29
  • 35
  • 3
    This is a duplicate of [Ruby Block Syntax Error](http://StackOverflow.Com/q/6854283/), [Code block passed to `each` works with brackets but not with `do`-`end` (ruby)](http://StackOverflow.Com/q/6718340/), [Block definition - difference between braces and `do`-`end` ?](http://StackOverflow.Com/q/6179442/), [Ruby multiline block without `do` `end`](http://StackOverflow.Com/q/3680097/), [Using `do` block vs brackets `{}`](http://StackOverflow.Com/q/2122380/) and [What is the difference or value of these block coding styles in Ruby?](http://StackOverflow.Com/q/533008/). – Jörg W Mittag Jul 28 '11 at 08:19
  • Parts of a pry session using Ruby-2.2.0 in this posts date. pp_hash = x.map do |i| {:value => i, :double => (i*2)} end => [{:value=>1, :double=>2}, {:value=>2, :double=>4}, {:value=>3, :double=>6}] pp_hash.join(",") "{:value=>1, :double=>2},{:value=>2, :double=>4},{:value=>3, :double=>6}" which is probably more desirable in todays usages of Json but that's a matter of style for just the reading of the output. Sometimes it just doesn't matter which one you're going to pass around as long as your code can handle the right type. pp_hash = pp_hash.join(",") – Douglas G. Allen Feb 18 '15 at 18:29
  • This is what I really got before going off on a tangent. This is the first part in pry.... [53] pry(main)> pp x.map do |i| {:key => i, :value => (i*2)} end # => # – Douglas G. Allen Feb 18 '15 at 18:34

1 Answers1

15

It's because you're calling

pp x.map

and passing a block to pp (which ignores it)

As explained in the Programming Ruby book

Braces have a high precedence; do has a low precedence

So, effectively, braces tie to the function call closest to them (x.map) whereas do binds to the furthest away (pp). That's a bit simplistic but it should explain this situation

Community
  • 1
  • 1
Gareth
  • 133,157
  • 36
  • 148
  • 157
  • Thanks @Gareth, do you know of any formal reference? Some language specification, etc? – rkj Jan 07 '09 at 13:15