Amphiaraus has asked for the wisdom of the Perl Monks concerning the following question:

I am using the Tree::Nary module in a Perl program of mine in which I recently added a recursive function, recurse_tree.

I am finding that each time I call recurse_tree, an empty node, containing no data, is being added to my N-ary tree.

I need to traverse the children of parent nodes using Tree::Nary->children_foreach. To allow Tree::Nary->children_foreach to take each node in the {children} linked list as input I have had to include within my recurse_tree function the following wrapper function:

my $call_recurse_tree = sub { my $node = shift; &recurse_tree($node); };


Which is used used by Tree::Nary->children_foreach as follows:

# PROCESS CHILDREN LIST: recurse_tree will be called on each +child of the input Dir Node Tree::Nary->children_foreach($node, $Tree::Nary::TRAVERSE_ALL +, $call_recurse_tree);


Empty nodes are being added to my N-ary tree in recurse_tree, even though neither this function nor its helpers calls any Tree::Nary append or prepend function -- yet empty, bogus nodes are somehow getting into my tree, one for each call to recurse_tree.

Has anyone ever had a similar problem with Tree::Nary? Could my workaround "my call_recurse_tree = sub" be the culprit? What really makes this problem maddening is that both recurse_tree and its helpers are receiving the node of the N-ary tree BY VALUE, not BY REFERENCE, so they ought not to be able to change my actual N-ary tree -- they are only working on local copies of this tree.

Thank You,
Amphiaraus

Replies are listed 'Best First'.
Re: Tree::Nary -- my program is creating phantom nodes
by tilly (Archbishop) on Dec 18, 2008 at 23:13 UTC
    Tree::Nary, my impression is that it is a bad idea. That said I can provide partial enlightenment. When you pass a tree to a subroutine it copies the reference to the root of the data structure, not the data. So you get a shallow copy. Unless you use something like Storable's clone, the routines you pass data to can therefore affect your copy of tree.

    Without code I can't say how or where it is happening, and as I said I wuoldn't worry about it too much - I would rewrite code more efficiently in a more native fashion.

      My recurse_tree function is creating "phantom nodes" (i.e. Tree:Nary nodes with an empty {data} field ) both when I take in the subtree node by reference, and when I take it in by value, i.e.:

      # By reference my $root_address = shift; my $root = $$root_address;

      AND
      # By value my $root = shift;

      both lead to creating of phantom nodes in my N-ary tree. These tend to be close to the top of the tree, but print-traversal of my Tree::Nary tree shows they are not the immediate children of my Tree's root. Also debug statements that use the Tree::Nary->n_nodes function show these phantom nodes are being made in my recurse_tree() function and nowhere else. Neither recurse_tree nor its helper, find_subtree(), use the Tree::Nary append or prepend functions.

      I am on vacation but as soon as I can I will post a copy of my recurse_tree() function here.

      Thank You,
      Amphiaraus
        Please read this article and try to understand the difference between a shallow copy and a deep copy. Once you understand that you will understand why it didn't make a difference when you tried to pass the structure by value or reference. But it would make a difference if you copied it with Storable's dclone.

        I obviously couldn't tell you why the code changed the tree. I've already indicated that I wouldn't worry about it too much, I would rewrite the code in question.

Re: Tree::Nary -- my program is creating phantom nodes
by ikegami (Patriarch) on Dec 18, 2008 at 19:53 UTC

    Empty nodes are being added to my N-ary tree in recurse_tree

    If that's what you think, how come you didn't post recurse_tree?

    Please post a minimal program that demonstrates the problem.