Given,
def wrapper &block
(1..5).inject yield
end
proc = Proc.new {|sum, n| sum + n }
Why can't I do this call?
wrapper &proc
=> NoMethodError: undefined method `+' for nil:NilClass
When looking inside, I see that inject has not been able to assign the memo or the obj, as rewriting the proc to be proc = Proc.new {|memo, obj| puts memo ; puts obj }
returns 10 iterations of nothing. I also noted that (1..5).inject
takes only one argument, what it passes in as the initial memo, and that technically it doesn't the block as a real argument.
The way to do it is
def wrapper &block
( 1..5 ).reduce &block
end
p = proc { |a, b| a + b }
wrapper &p
#=> 15
But in your question, you interestingly attempted to use yield
. When you use yield
, you don't need to explicitly mention the &block
parameter – a method cannot refuse a block, which is always callable by yield
inside the method. However, yield
expects arguments. The way to use yield
to achieve your goal is:
def wrapper_2
( 1..5 ).reduce { |accumulator, input| yield accumulator, input }
end
This formulation is still a bit awkward. It turns out that there is a secret way to obtain the block inside a method even if you do not specify the &block
parameter, and that is by using unadorned Proc.new
inside the method:
def wrapper_3
( 1..5 ).reduce &Proc.new
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With