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

map(&;:name)在Ruby中是什么意思?,ruby,syntax,operators,parameter-passing,Ruby,Syntax,Operators,Parameter Passing,我在以下文件中找到此代码: map(&:name)中的(&:name)是什么意思?它是tags.map{| tag | tag.name}.join(“”)的缩写它是tags.map{| tag tag.name}.join(“”)的缩写 def tag_names @tag_names || tags.map { |tag| tag.name }.join(' ') end 相当于 def tag_names @tag_names || tags.map { |tag| tag.na

我在以下文件中找到此代码:


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

它是
tags.map{| tag | tag.name}.join(“”)的缩写
它是
tags.map{| tag tag.name}.join(“”)的缩写

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

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

它是tags.map(&:name.to_proc.join(“”)的缩写

如果
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

它是tags.map(&:name.to_proc.join(“”)的缩写

如果
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

另一个很酷的速记,很多人都不知道,是

array.each(&method(:foo))
这是

array.each { |element| foo(element) }
通过调用
方法(:foo)
我们从
self
获取了一个
方法
对象,该对象表示它的
foo
方法,并使用
表示它有一个
to_proc
将其转换为
proc

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

["bar", "baz", "foo"].any? { |str| str == "foo" }
还有一种无点方式:

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

首选的方法应该是可读性最好的方法。

另一种很酷的速记方法是

array.each(&method(:foo))
这是

array.each { |element| foo(element) }
通过调用
方法(:foo)
我们从
self
获取了一个
方法
对象,该对象表示它的
foo
方法,并使用
表示它有一个
to_proc
将其转换为
proc

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

["bar", "baz", "foo"].any? { |str| str == "foo" }
还有一种无点方式:

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

首选的方法应该是可读性最好的方法。

同时让我们注意到,符号和
#to_proc
magic可以用于任何类,而不仅仅是符号。许多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!"]
符号
&
通过在其操作数上发送
至_proc
消息来工作,在上述代码中,该操作数属于数组类。由于我在数组上定义了
#to_proc
方法,因此该行变为:

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

同时,让我们注意到,ampersand
#to_proc
magic可以用于任何类,而不仅仅是符号。许多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!"]
符号
&
通过在其操作数上发送
至_proc
消息来工作,在上述代码中,该操作数属于数组类。由于我在数组上定义了
#to_proc
方法,因此该行变为:

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

Josh Lee的答案几乎是正确的,除了等价的Ruby代码应该如下所示

class Symbol
  def to_proc
    Proc.new do |receiver|
      receiver.send self
    end
  end
end
不是

使用此代码,当执行
print[[1,'a']、[2,'b']、[3,'c']].map(&:first)
时,Ruby将第一个输入
[1,'a']
拆分为1和'a'以给出
obj
1和
args*
'a'以导致错误,因为Fixnum对象1没有方法self(即:first)


当执行
[[1,'a'],[2,'b'],[3,'c']]时,

  • :first
    是一个符号对象,因此当
    &:first
    作为参数提供给map方法时,将调用Symbol#to _proc

  • map使用参数
    [1,'a']
    将调用消息发送到:first.to_proc,例如,
    :first.to_proc.call([1,'a'])

  • 符号类中的to_proc过程向带有参数(:first)的数组对象(
    [1,'a']
    )发送发送消息,例如,
    [1,'a'])。执行发送(:first)

  • 迭代
    [[1,'a'],[2,'b'],[3,'c']]
    对象中的其余元素


  • 这与执行
    [[1,'a'],[2,'b'],[3,'c']].map(| e | e.first)
    表达式相同。

    Josh Lee的答案几乎正确,只是等效的Ruby代码应该如下所示

    class Symbol
      def to_proc
        Proc.new do |receiver|
          receiver.send self
        end
      end
    end
    
    不是

    使用此代码,当执行
    print[[1,'a']、[2,'b']、[3,'c']].map(&:first)
    时,Ruby将第一个输入
    [1,'a']
    拆分为1和'a'以给出
    obj
    1和
    args*
    'a'以导致错误,因为Fixnum对象1没有方法self(即:first)


    当执行
    [[1,'a'],[2,'b'],[3,'c']]时,

  • :first
    是一个符号对象,因此当
    &:first
    作为参数提供给map方法时,将调用Symbol#to _proc

  • map使用参数
    [1,'a']
    将调用消息发送到:first.to_proc,例如,
    :first.to_proc.call([1,'a'])

  • 符号类中的to_proc过程向带有参数(:first)的数组对象(
    [1,'a']
    )发送发送消息,例如,
    [1,'a'])。执行发送(:first)

  • 迭代
    [[1,'a'],[2,'b'],[3,'c']]
    对象中的其余元素


  • 这与执行
    [[1,'a'],[2,'b'],[3,'c']].map(|e | e.first)
    表达式是一样的。

    这里发生了两件事,理解这两件事很重要

    如其他答案所述,正在调用
    Symbol#to_proc
    方法

    但是在s上调用了执行_proc
    的原因
    array.map { |element| element.name }