what happened when pass a method to iterator method

依然范特西╮ 提交于 2019-12-30 10:41:54

问题


As we know, wo can pass a method to a iterator method by a &: prefix.
For example:

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

Here is the problem, when I write a method, pass a method with &: prefix to it, I got a error message: "ArgumentError: no receiver given".
Let me show the code:

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

What do I missing, How the map like method of Array handle it


回答1:


Here's what works. Explanation below.

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"

The &: construct is called Symbol#to_proc. It turns symbol into a proc. This proc expects a receiver as a first argument. The remaining arguments are used to call the proc. You're not passing any arguments, hence the "receiver not given" error.

Here's a demonstration of additional arguments:

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"

Here's a definition of Symbol#to_proc from some blog post from 2008. Modern Symbol#to_proc seems to be implemented in C, but this can still help the understanding.

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


来源:https://stackoverflow.com/questions/13365452/what-happened-when-pass-a-method-to-iterator-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!