From: Joel VanderWerf Date: 2009-07-05T11:17:57+09:00 Subject: Re: to_proc and Proc/block conversion with & 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) Hi, Russ, It may be helpful to think of the & in words.map(&something) not as an operator (in your example, you have demonstrated why that picture is wrong), but as a way to access a special "slot", different from the positional arguments, for passing an argument of a special kind. The only kind of object the slot can contain is a Proc (and ruby makes an effort to convert the passed object to Proc, using, um, #to_proc). Using this slot is mutually exclusive with having a _syntactic block_ in the calling context: words.map do...end But from the perspective of the #map method's implementation, these two cases are functionally equivalent. If you were implementing #map, you could access the caller's code in either of the above cases by any of these means: constructing a Proc using &: def map(&b) b.call ... end or equivalently with Proc.new: def map b = Proc.new b.call end or (somewhat differently) by yielding: def map yield ... end Note that the performance is generally better if you avoid constructing Proc objects (assuming you don't need to store them somewhere between method calls).[1] In other words, avoid & and use yield. But this isn't usually significant. [1] https://groups.google.com/group/ruby-talk-google/msg/e464fd85eb82b3b6 -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407