def double(a)
a*2
end
method_object = method(:double)
and here’s my question, how does this code:
[1,3,5,6].map(&method_object)
achieve the same result of
[1,3,5,6].map {|x| method_object.call(x)}
in the Ruby document, the Array#map only can have block, not normal parameter
ary.collect {|item| block } → new_ary ary.map {|item| block } → new_ary ary.collect → an_enumerator ary.map → an_enumerator
Simply put, the ampersand
&is used to “pack / unpack” a method object to a block, so the effect is more-less the same as if you passed the block.You can “get” the block that has been passed to your method by:
This will be similar to calling
yieldand not declaring&fooas parameter. I think binding might differ between the two approaches, but in most cases the effect is what you would expect (if I am mistaken, please correct).Of course, the ampersand works the other way around – if a method expects a block and you have a proc object, you can simply prepend it with
&, just as you wrote. To be more precise,&callsto_procmethod of the passed object (Rails uses this in a manner similar to described in this entry about to_proc.I hope that this answers some of your doubts. In case there is a mistake in what I wrote, feel free to correct it.
Readings you might find useful: