What does map(&:name) mean in Ruby?

I found this code in a RailsCast:

def tag_names
  @tag_names || tags.map(&:name).join(' ')
end

What does the (&:name) in map(&:name) mean?


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

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.


这相当于

def tag_names
  @tag_names || tags.map { |tag| tag.name }.join(' ')
end
链接地址: http://www.djcxy.com/p/9946.html

上一篇: PHP期待T

下一篇: 在Ruby中map(&:name)是什么意思?