NAME

NumberedTree - a thin N-ary tree structure with a number for each item.

SYNOPSYS

use NumberedTree;
my $tree = new('I am the root of the tree');
$tree->append('I am a child');
$tree->append('Me too');

while (my $branch = $tree->nextNode) {
   $branch->delete if ($branch->getValue eq 'Stuff I dont want');
}

my $itemId = what_the_DB_says;
print join ' --- ', $tree->follow($itemId); # a list of items up to itemId.

etc. 

DESCRIPTION

NumberedTree is a special N-ary tree with a number for each node. This is  
useful on many occasions. The first use I  found for that (and wrote this for) 
was to store information about the selected item as a number instead of storing
the whole value which is space-expensive.
Every tree also has a lucky number of his own that distinguishes it from other
trees created by the same module.
This module is thin on purpose and is meant to be a base class for stuff that 
can make use of this behaveiour. For example, I wrote NumberedTree::DBTree
which ties a tree to a table in a database, and Javascript::Menu which uses 
this tree to build a Menu.

BUILDING AND DESTROYING A TREE

NumberedTree->new(VALUE)

There is only one correct way to start an independent tree with its own lucky number from scratch: calling the class function new. Using new as a method is wrong because it will create a node for the same tree but the tree won't know of its existence. See below.

$tree->clone(LUCKY_NUMBER)

Another way to obtain a new tree object is to clone an existing one. The clone method does that. The original object remains untouched. You have the option of supplying a lucky number instead of letting the module decide, but use this with caution, since there is no guarantee that you give a good number. Best to not use it.

$tree->append(VALUE)

This is the correct way to add an item to a tree or a branch thereof. Internally uses $tree->new but does other stuff.

$tree->delete

Deletes the child pointed to by the cursor (see below) and returns the deleted item. Note that it becomes risky to use this item since its parent tree knows nothing about it from the moment it is deleted and you can cause collisions so use with caution.

ITERATING OVER CHILD ITEMS

The cursor

Every node in the tree has its own cursor that points to the current item. When you start iterating, the cursor is placed just before the first child. When you are at the last item, trying to move beyond the last item will put the cursor after the last item (which will result in an undef value, signalling the end) but the next attempt will cause the cursor to start over from the first child.

Methods for iteration

nextNode

Moves the cursor one child forward and returns the pointed child.

reset

Resets the cursor to point before the first child.

savePlace

Allows you to save the cursor's place, do stuff, then go back. There is only one save, though, so don't try to nest saves.

restorePlace

Tries to set the cursor to the item at the same place as it was when its place was saved and returns true on success. If the saved place doesn't exist anymore returns undef. Note: If you deleted items from the tree you might not get to the right place.

ACCESSORS

The following are available:

get/setValue

Gets or sets the Value property of a node.

getNumber

Gets the number of the node within its NumberedTree. There is no setter since this number is special.

getLuckyNumber

Gets the number of the main tree that the node is a member of. Again, there is no setter since this is special.

childCount

Gets the number of childs for this node.

THINGS YOU CAN DO WITH NODE NUMBERS

Well, I didn't include the node numbers just for fun, this is actually very needed sometimes. There are three basic service methods that use this (subclasses may add to this):

getSubTree(NUMBER)

If a node who's number is given is a member of the subtree that the method was invoked on, that node will be returned, undef otherwise.

listChildNumbers(NUMBER)

returns a list of all numbers of nodes that are decendants (any level) of the subtree whose number is given. Number is optional, the node's own number is used if no number is specifically requested.

follow(NUMBER)

returns a list of all values starting from the decendant node with the requested number, through every parent of the node and up to the node the method was invoked on. If no such node exists, returns an empty list.

OTHER METHODS

There are two methods that apply a certain subroutine to whole trees:

deepProcess (SUBREF, ARG, ARG, ...)

For each child of the node, runs the subroutine referenced by SUBREF with an argument list that starts with a reference to the child being processed and continues with the rest of the arguments passed to deepProcess.

allProcess (SUBREF, ARG, ARG, ...)

does the same as deepProcess but runs on the root node first.

BUGS AND PROBLEMS

Works pretty well for me. If you found anything, please send a bug report: <http://rt.cpan.org/NoAuth/Bugs.html?Dist=NumberedTree> or send mail to <bug-NumberedTree#rt.cpan.org>

AUTHOR

Yosef Meller, < mellerf@netvision.net.il >

COPYRIGHT AND LICENSE

Copyright 2003 by Yosef Meller

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 392:

You forgot a '=back' before '=head1'