0

receiver_method(&:method) functionality seems clear enough, yet I find a gap in the explanations* about the assignment to 'obj' as in—

class Symbol
  def to_proc #<parameter notably absent>
    Proc.new { |obj, *args|
      obj.send (self, *args)
    }
  end
end

How does this assign the receiver method's object/passed argument as 'obj'?


* What does map(&:name) mean in Ruby?

* https://www.skorks.com/2013/04/ruby-ampersand-parameter-demystified/

1 Answers1

1

How does Ampersand pass arguments into #to_proc as “obj”? — receiving_method(&:method)

Ampersand does not pass anything anywhere. Ampersand converts the argument to a proc instance, implicitly calling to_proc on it. And passes the result as a block to the caller.

Let’s stick with the example:

%w[42 foo].map(&:to_i)
#⇒ [42, 0]

What’s going on here?

to_i is being converted to proc as you shown in the OP

#                            ⇓⇓⇓⇓⇓
proc { |obj, *args| obj.send(:to_i, *args) }

• we pass this proc to the caller (without lose of generality, I’d write it with block syntax for the sake of clarity

%w[42 foo].map do |obj, *args|
  obj.send(:to_i, *args)
end

NB! *args is off-side here, since map passes the single argument to the block:

%w[42 foo].map do |obj|
  obj.send(:to_i)
end

That would map:

'42' → '42'.send(:to_i) ≡ '42'.to_i → 42,
'foo' → 'foo'.send(:to_i) ≡ 'foo'.to_i → 0,

yielding:

#⇒ [42, 0]
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160