Search code examples
rubyblocktree-traversal

Ruby: Yielding from a method that takes arguments?


I've written a very simple, recursive, tree-traversal method in ruby. I want to yield the results of this traversal so that I can easily iterate through the nodes of the tree.

def bottom_up_traversal (node)
    if(node.has_leaf_children?)
        node.children.each{|i| yield i} 
    else
        node.children.each{|i| bottom_up_traversal(i)}
        yield node
    end

end

And when I attempt to call it, like:

 bottom_up_traversal(@root){|this_node| puts this_node }

I get a 'Wrong number of arguments (0 for 1)'. I know this is probably just something silly i'm doing with syntax, but I cannot find any (even basic) examples of this being done....which leads me to believe that I'm misunderstanding how I should be using code-bocks (something which is admittedly new to me)

So, could you perhaps tell me how I'm supposed to call this method, or where I've gone wrong?


Solution

  • In the end it wasn't the original method call, but the way the method recursively calls itself that was the issue, which stemmed not from me not really understanding how code-blocks work it seems.

    Phillip's answer with extra 'yield self' calls worked perfectly.

    Thank you very much!

    def bottom_up_traversal (node, &block)
        if(node.has_leaf_children?)
            node.children.each{|i| yield i} 
            yield node
        else    
            node.children.each{|i| bottom_up_traversal(i, &block)}
            yield node
        end
    end
    

    called like

    bottom_up_traversal(@root){|this_node| puts this_node }
    

    traverses them in perfect order.