3

众所周知,wo 可以通过&:前缀将方法传递给迭代器方法。
例如:

["a", "b"].map(&:upcase) #=> ["A", "B"] 
def rettwo
  2
end
["a", "b"].map(&:rettwo) #=> [2, 2]

这是问题所在,当我编写一个方法时,将一个带&:前缀的方法传递给它,我收到一条错误消息:“ArgumentError: no receiver given”。
让我展示一下代码:

def a_simple_method &proc
  puts proc.class # it shows `Proc`
  proc.call
end
def a_iterator_method
  puts yield
end

a_simple_method &:rettwo #=> ArgumentError: no receiver given
a_iterator_method &:rettwo #=> ArgumentError: no receiver given

我错过了什么map,Array 的 like 方法如何处理它

4

1 回答 1

4

这是有效的。说明如下。

class String
  def rettwo
    self + self
  end
end

def a_simple_method &proc
  proc.call('a')
end

def a_iterator_method
  yield 'b'
end

a_simple_method(&:rettwo) # => "aa"
a_iterator_method(&:rettwo) # => "bb"

&:构造称为Symbol#to_proc。它将符号变成一个过程。这个过程需要一个接收器作为第一个参数。其余参数用于调用 proc。您没有传递任何参数,因此出现“未给出接收者”错误。

这是其他参数的演示:

class String
  def say name
    "#{self} #{name}"
  end
end

def a_simple_method &proc
  proc.call('hello', 'ruby')
end


a_simple_method(&:say) # => "hello ruby"

这是 2008 年的一些博客文章中对 Symbol#to_proc 的定义。现代 Symbol#to_proc 似乎是用 C 实现的,但这仍然有助于理解。

class Symbol
  def to_proc
    Proc.new { |*args| args.shift.__send__(self, *args) }
  end
end
于 2012-11-13T17:23:47.453 回答