我在RailsCast中找到了这段代码:

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

map(&:name)中的(&:name)是什么意思?


当前回答

Map (&:name)接受一个可枚举对象(在您的例子中是标签),并为每个元素/标签运行name方法,输出该方法的每个返回值。

这是一个简写

array.map { |element| element.name }

返回元素(标签)名称的数组

其他回答

它是tags.map(&:name.to_proc)的简写。加入(' ')

如果foo是一个带有to_proc方法的对象,那么你可以将它传递给一个名为&foo的方法,该方法将调用foo。To_proc并使用它作为方法的块。

Symbol#to_proc方法最初是由ActiveSupport添加的,但已经集成到Ruby 1.8.7中。这是它的实现:

class Symbol
  def to_proc
    Proc.new do |obj, *args|
      obj.send self, *args
    end
  end
end

它等价于

def tag_names
  @tag_names || tags.map { |tag| tag.name }.join(' ')
end

它的意思是

array.each(&:to_sym.to_proc)

这里:name是指向标记对象的方法名的符号。 当我们将&:name传递给map时,它将把name作为一个proc对象。 简而言之,tags.map(&:name)充当:

tags.map do |tag|
  tag.name
end

同时让我们也注意到& #to_proc魔法可以对任何类工作,而不仅仅是符号。很多ruby会选择在Array类上定义#to_proc:

class Array
  def to_proc
    proc { |receiver| receiver.send *self }
  end
end

# And then...

[ 'Hello', 'Goodbye' ].map &[ :+, ' world!' ]
#=> ["Hello world!", "Goodbye world!"]

&的工作原理是在其操作数上发送to_proc消息,在上面的代码中,操作数属于Array类。因为我在Array上定义了#to_proc方法,所以这一行变成:

[ 'Hello', 'Goodbye' ].map { |receiver| receiver.send( :+, ' world!' ) }