Ruby ampersand colon shortcut
RubyRuby Problem Overview
> Possible Duplicate:
> What does map(&:name) mean in Ruby?
In Ruby, I know that if I do:
some_objects.each(&:foo)
It's the same as
some_objects.each { |obj| obj.foo }
That is, &:foo
creates the block { |obj| obj.foo }
, turns it into a Proc, and passes it to each. Why does this work? Is it just a Ruby special case, or is there reason why this works as it does?
Ruby Solutions
Solution 1 - Ruby
Your question is wrong, so to speak. What's happening here isn't "ampersand and colon", it's "ampersand and object". The colon in this case is for the symbol. So, there's &
and there's :foo
.
The &
calls to_proc
on the object, and passes it as a block to the method. In Ruby, to_proc
is implemented on Symbol
, so that these two calls are equivalent:
something {|i| i.foo }
something(&:foo)
So, to sum up: &
calls to_proc
on the object and passes it as a block to the method, and Ruby implements to_proc
on Symbol
.
Solution 2 - Ruby
There's nothing special about the combination of the ampersand and the symbol. Here's an example that (ab)uses the regex:
class Regexp
def to_proc
->(str) { self =~ str ; $1 }
end
end
%w(station nation information).map &/(.*)ion/
=> ["stat", "nat", "informat"]
Or integers.
class Integer
def to_proc
->(arr) { arr[self] }
end
end
arr = [[*3..7],[*14..27],[*?a..?z]]
arr.map &4
=> [7, 18, "e"]
Who needs arr.map(&:fifth)
when you have arr.map &4
?