Hi --
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
···
On Sun, 5 Jul 2009, Russ McBride wrote:
--
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\)