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

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

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


当前回答

(&:name)是(&:name.to_proc)的缩写,与标签相同。映射{|t| t.name}。加入(' ')

to_proc实际上是用C语言实现的

其他回答

另一个很酷的简写,很多人不知道,是

array.each(&method(:foo))

这是一个简写

array.each { |element| foo(element) }

通过调用method(:foo),我们从self中获取了一个method对象,该对象表示它的foo方法,并使用&表示它有一个to_proc方法,该方法将它转换为Proc。

这是非常有用的,当你想做点自由风格的事情。一个例子是检查数组中是否有字符串等于字符串“foo”。有一种传统的方式:

["bar", "baz", "foo"].any? { |str| str == "foo" }

还有一种简单的方法:

["bar", "baz", "foo"].any?(&"foo".method(:==))

首选的方式应该是最易读的方式。

它的意思是

array.each(&:to_sym.to_proc)

虽然我们已经有了很好的答案,但从初学者的角度来看,我想添加额外的信息:

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

这意味着,您正在将另一个方法作为参数传递给map函数。 (实际上,您传递的是一个符号,该符号将被转换为proc。但在这种特殊情况下,这并不那么重要)。

重要的是,您有一个名为name的方法,它将被map方法用作参数,而不是传统的块样式。

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

这是一个简写

array.map { |element| element.name }

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

同时让我们也注意到& #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!' ) }