将方法传递给迭代器方法时发生了什么

时间:2012-11-13 17:16:46

标签: ruby methods proc

我们知道,wo可以通过&:前缀将方法传递给迭代器方法 例如:

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

问题是,当我编写一个方法时,将一个带有&:前缀的方法传递给它,我收到一条错误消息:“ArgumentError:没有给出接收者”。
让我展示一下代码:

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方法如何处理它

1 个答案:

答案 0 :(得分: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。这个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的定义。现代符号#to_proc似乎是用C实现的,但这仍然有助于理解。

class Symbol
  def to_proc
    Proc.new { |*args| args.shift.__send__(self, *args) }
  end
end