Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursion in yield

Tags:

ruby

recursion

So i am trying to do something like this:

def func(x,y)
     if x.length == 1 then
         n = x.pop()
         yield(n,y)
     else
         n = x.pop()
         yield(n,func(x,y))
     end
end

calling it like:

a = func([1,2,3,4,5],0) do |x,y|
    x+y
end

Is it possible to do something like this? I keep getting no block given (yield) (LocalJumpError).

I even tried doing something a little different:

def func(x,y)
    func(x,y) do |tail|
        ..
    end
end

but no luck

Thanks.

like image 708
Matt Avatar asked Nov 24 '10 04:11

Matt


2 Answers

Yes, you can take the block as an argument explicitly:

def func(x, y, &block)

You can still yield to it with the yield keyword, but you can also pass it as you recurse:

yield(n, func(x, y, &block))

The & in both cases means that the block argument is not a normal argument, but represents the block that can be attached to any Ruby method call.

like image 132
Paige Ruten Avatar answered Sep 28 '22 08:09

Paige Ruten


You are missing to pass the block in the recursive call.
The recursive call should be like as below:-

yield(n,func(x,y)) { |x,y| x+y})

Since you missed to pass the block in the recursive call, when the code hits:-

     if x.length == 1 then
     n = x.pop()
     yield(n,y) <<<< Here 

the method func doesn't have block passed as argument,in the recursive call, but ruby tries to call a non-existent block and hence the error.

like image 23
Hemanth Avatar answered Sep 28 '22 09:09

Hemanth