Reputation: 22064
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
Upvotes: 2
Views: 223
Reputation: 1239
you can extend class integer:
class Integer
def double
self*2
end
end
[1,2,3,4].map(&:double)
[
[0] 2,
[1] 4,
[2] 6,
[3] 8
]
Upvotes: 0
Reputation: 7188
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:
def method_with_block(&foo)
# do something here
foo.call
# do something else
end
This will be similar to calling yield
and not declaring &foo
as 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, &
calls to_proc
method 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:
Upvotes: 3