From: "David A. Black" Date: 2009-07-05T10:10:55+09:00 Subject: Re: to_proc and Proc/block conversion with & Hi -- On Sun, 5 Jul 2009, Russ McBride wrote: > > map requires a block, right? So this works: > > words = %w(ardvark anteater llama) > > arr = words.map { |x| x + "!" } > arr #--> [ardvark!, anteater!, llama!] > > But this doesn't: > > arr2 = words.map lambda{ |x| x + "!"} #--> ArgumentError: wrong > number of arguments (1 for 0) > > > We can trigger a call to some object's to_proc method with the ampersand. > For example, this > will trigger the symbol's to_proc method, assuming there is one: > > upcase_words = words.map(&:upcase) > > and if we have already have this: > > class Symbol > def to_proc > lambda{ |x| x.send(self) } > end > end > > then we get: > #--> [ARDVARK, ANTEATER, LLAMA] > > But, the to_proc method here is returning a Proc, not a block! So why does > this work? There's no such thing as returning a block. A block is a syntactic construct. You can, however, have a Proc object in block position, playing the block role, courtesy of &. (We don't have a really perfect term for that, I think.) > As far as I can tell, the ampersand must be doing 2 things: > 1- triggering the call to to_proc > 2- converting the returned Proc object into a block for map to handle. > > Is this right? Yes; the & means: take what's to the right of it (which can be any expression), evaluate it, call to_proc on the resulting object, and use the return value of to_proc to play the code block role. In the case of a lambda, to_proc just returns the receiver. So you can do: array.map &lambda {|x| x * 10 } Without the &, you're just putting an argument in method-argument position. Using a Proc object as a method argument does not trigger any special or block-related behavior. That comes entirely from the ampersand. David -- David A. Black / Ruby Power and Light, LLC Ruby/Rails consulting & training: http://www.rubypal.com Now available: The Well-Grounded Rubyist (http://manning.com/black2) Training! Intro to Ruby, with Black & Kastner, September 14-17 (More info: http://rubyurl.com/vmzN)