I found this code in a RailsCast:
def tag_names
@tag_names || tags.map(&:name).join(\' \')
end
What does the (&:name)
Another cool shorthand, unknown to many, is
array.each(&method(:foo))
which is a shorthand for
array.each { |element| foo(element) }
By calling method(:foo)
we took a Method
object from self
that represents its foo
method, and used the &
to signify that it has a to_proc
method that converts it into a Proc
.
This is very useful when you want to do things point-free style. An example is to check if there is any string in an array that is equal to the string "foo"
. There is the conventional way:
["bar", "baz", "foo"].any? { |str| str == "foo" }
And there is the point-free way:
["bar", "baz", "foo"].any?(&"foo".method(:==))
The preferred way should be the most readable one.
Although we have great answers already, looking through a perspective of a beginner I'd like to add the additional information:
What does map(&:name) mean in Ruby?
This means, that you are passing another method as parameter to the map function. (In reality you're passing a symbol that gets converted into a proc. But this isn't that important in this particular case).
What is important is that you have a method
named name
that will be used by the map method as an argument instead of the traditional block
style.
map(&:name) takes an enumerable object (tags in your case) and runs the name method for each element/tag, outputting each returned value from the method.
It is a shorthand for
array.map { |element| element.name }
which returns the array of element(tag) names
It's shorthand for tags.map(&:name.to_proc).join(' ')
If foo
is an object with a to_proc
method, then you can pass it to a method as &foo
, which will call foo.to_proc
and use that as the method's block.
The Symbol#to_proc
method was originally added by ActiveSupport but has been integrated into Ruby 1.8.7. This is its implementation:
class Symbol
def to_proc
Proc.new do |obj, *args|
obj.send self, *args
end
end
end