Tree(3)
okay bestie, welcome to Tree(3) β User Contributed Perl Documentation. It's giving N-ary tree, no cap.
β¨ NAME β¨
Tree β an N-ary tree. That's the whole name, periodt.
π SYNOPSIS π
Here's the group chat in code form, fr fr:
my $tree = Tree->new( 'root' );
my $child = Tree->new( 'child' );
$tree->add_child( $child );
$tree->add_child( { at => 0 }, Tree->new( 'first child' ) );
$tree->add_child( { at => -1 }, Tree->new( 'last child' ) );
$tree->set_value( 'toor' );
my $value = $tree->value;
my @children = $tree->children;
my @some_children = $tree->children( 0, 2 );
my $height = $tree->height;
my $width = $tree->width;
my $depth = $tree->depth;
my $size = $tree->size;
if ( $tree->has_child( $child ) ) {
$tree->remove_child( $child );
}
$tree->remove_child( 0 );
my @nodes = $tree->traverse( $tree->POST_ORDER );
my $clone = $tree->clone; # See remarks under clone() re deep cloning.
my $mirror = $tree->clone->mirror;
$tree->add_event_handler({
add_child => sub { ... },
remove_child => sub { ... },
value => sub { ... },
});
my $old_default_error_handler = $tree->error_handler(Tree->DIE);
my $old_object_error_handler = $tree->error_handler($tree->DIE);
π DESCRIPTION π
Okay so this module is meant to be a full-featured N-ary tree representation. It's got configurable error-handling and a simple events system that lets you do transparent persistence to a whole variety of datastores. It's derived from Tree::Simple, but lowkey has a simpler interface and much, much more. Periodt.
πΈ METHODS πΈ
π Constructors π
π new([$value]) π
Here, [] indicate an optional parameter. iykyk.
This will return a Tree object. It will accept one parameter which, if passed, will become the value (accessible by value()). All other parameters will be ignored. Not me ignoring extra args, but okay.
If you call $tree->new([$value]), it will instead call clone(), then set the value of the clone to $value.
π clone() π
This will return a clone of $tree. The clone will be a root tree, but all children will be cloned.
If you call Tree->clone([$value]), it will instead call new($value).
NOTE: thevalueis merely a shallow copy. This means that all references will be kept, but themetadata attached to each node is not copied. Don't get it twisted.
See Tree::DeepClone and t/Tree_DeepClone/*.t if you want deep cloning, which is defined to mean that the meta data attached to each node is also copied into the clone. Slay.
π Behaviors π
π add_child([$options], @nodes) π
This will add all the @nodes as children of $tree. $options is an optional unblessed hashref that specifies options for add_child(). The optional parameters are:
atβ This specifies the index to add@nodesat. If specified, this will be passed intosplice(). The only exceptions are if this is0, it will act as anunshift(). If it is unset or undefined, it will act as apush(). Lastly, if it is out of range (too negative or too big [beyond the number of children]) the child is not added, and an error msg will be available inlast_error(). So watch that range, bestie.
add_child() resets last_error() upon entry.
π remove_child([$options], @nodes) π
Here, [] indicate an optional parameter.
This will remove all the @nodes from the children of $tree. You can either pass in the actual child object you wish to remove, the index of the child you wish to remove, or a combination of both. Mix and match, it's giving flexible.
$options is an optional unblessed hashref that specifies parameters for remove_child(). Currently, no parameters are used. So it's just vibing there.
remove_child() resets last_error() upon entry.
π mirror() π
This will modify the tree such that it is a mirror of what it was before. This means that the order of all children is reversed. Flip it, reverse it.
NOTE: This is a destructive action. It will modify the internal structure of the tree. If you wish to get a mirror, yet keep the original tree intact, use my $mirror = $tree->clone->mirror. Protect your original, bestie.
mirror() does not reset last_error() because it (mirror()) is implemented in Tree::Fast, which has no error handling.
π traverse([$order]) π
Here, [] indicate an optional parameter.
This will return a list of the nodes in the given traversal order. The default traversal order is pre-order. Default slay.
The various traversal orders do the following steps:
- Pre-order β This will return the node, then the first sub tree in pre-order traversal, then the next sub tree, etc. Use
$tree->PRE_ORDERas the$order. - Post-order β This will return each sub-tree in post-order traversal, then the node. Use
$tree->POST_ORDERas the$order. - Level-order β This will return the node, then all children of the node, then all grandchildren of the node, etc. Use
$tree->LEVEL_ORDERas the$order.
traverse() does not reset last_error() because it (traverse()) is implemented in Tree::Fast, which has no error handling.
π tree2string($options) π
Returns an arrayref of lines, suitable for printing. These lines do not end in "\n". So don't add your own newlines, bestie.
Draws a nice ASCII-art representation of the tree structure. It's giving art, literally.
The tree looks like:
Root. Attributes: {uid => "0"}
|--- H. Attributes: {uid => "1"}
| |--- I. Attributes: {uid => "2"}
| | |--- J. Attributes: {uid => "3"}
| |--- K. Attributes: {uid => "4"}
| |--- L. Attributes: {uid => "5"}
|--- M. Attributes: {uid => "6"}
|--- N. Attributes: {uid => "7"}
|--- O. Attributes: {uid => "8"}
|--- P. Attributes: {uid => "9"}
|--- Q. Attributes: {uid => "10"}
Or, without attributes:
Root
|--- H
| |--- I
| | |--- J
| |--- K
| |--- L
|--- M
|--- N
|--- O
|--- P
|--- Q
See scripts/print.tree.pl.
Example usage:
print map("$_\n", @{$tree -> tree2string});
If you do not wish to supply options, use tree2string() or tree2string({}).
Possible keys in the $options hashref (which defaults to {}):
no_attributes=>$Booleanβ If1, the node attributes are not included in the string returned. Default:0(include attributes). So default is to show them attributes.
Calls node2string($options, $node, $vert_dashes).
π State Queries π
π is_root() π
This will return true if $tree has no parent and false otherwise.
π is_leaf() π
This will return true if $tree has no children and false otherwise.
π has_child(@nodes) π
This will return true if $tree has each of the @nodes as a child. Otherwise, it will return false.
The test to see if a node is in the tree uses refaddr() from Scalar::Util, not the value of the node. This means @nodes must be an array of Tree objects. No cap, it's identity-based.
π get_index_for(@nodes) π
This will return the index into the children list of $tree for each of the @nodes passed in.
π Accessors π
π parent() π
This will return the parent of $tree.
π children( [ $idx, [$idx, ..] ] ) π
Here, [] indicate optional parameters.
This will return the children of $tree. If called in list context, it will return all the children. If called in scalar context, it will return the number of children. Context is everything, bestie.
You may optionally pass in a list of indices to retrieve. This will return the children in the order you asked for them. This is very much like an arrayslice. Ordered, iconic.
π root() π
This will return the root node of the tree that $tree is in. The root of the root node is itself. Main character energy.
π height() π
This will return the height of $tree. A leaf has a height of 1. A parent has a height of its tallest child, plus 1.
π width() π
This will return the width of $tree. A leaf has a width of 1. A parent has a width equal to the sum of all the widths of its children.
π depth() π
This will return the depth of $tree. A root has a depth of 0. A child has the depth of its parent, plus 1.
This is the distance from the root. It is useful for things like pretty-printing the tree.
π size() π
This will return the number of nodes within $tree. A leaf has a size of 1. A parent has a size equal to the 1 plus the sum of all the sizes of its children.
π value() π
This will return the value stored in the node.
π set_value([$value]) π
Here, [] indicate an optional parameter.
This will set the value stored in the node to $value, then return $self.
If $value is not provided, undef is used. Default undef, periodt.
π meta() π
This will return a hashref that can be used to store whatever metadata the client wishes to store. For example, Tree::Persist::DB uses this to store database row ids. iykyk.
It is recommended that you store your metadata in a subhashref and not in the top-level metadata hashref, keyed by your package name. Tree::Persist does this, using a unique key for each persistence layer associated with that tree. This will help prevent clobbering of metadata. Don't clobber, bestie.
π format_node($options, $node) π
Returns a string consisting of the node's name and, optionally, its attributes.
Possible keys in the $options hashref:
no_attributes=>$Booleanβ If1, the node attributes are not included in the string returned. Default:0(include attributes).
Calls hashref2string($hashref).
Called by node2string($options, $node, $vert_dashes).
You would not normally call this method. So maybe don't, bestie.
If you do not wish to supply options, use format_node({}, $node).
π hashref2string($hashref) π
Returns the given hashref as a string.
Called by format_node($options, $node).
π node2string($options, $node, $vert_dashes) π
Returns a string of the node name and attributes, with a leading indent, suitable for printing.
Possible keys in the $options hashref:
no_attributes=>$Booleanβ If1, the node attributes are not included in the string returned. Default:0(include attributes).
Ignore the parameter $vert_dashes. The code uses it as temporary storage. It's just internal storage, no cap.
Calls format_node($options, $node).
Called by tree2string($options).
π ERROR HANDLING π
okay so real talk: this is where you find out what the default error handlers actually do, and what a custom error handler is expected to do. that's the whole vibe of this section. bestie, read it before you go writing your own.
β¨ Error-related methods β¨
error_handler( [ $handler ] )β returns the error handler the tree is currently using, no cap. pass a value in and it sets the error handler for the tree instead. plot twist: if you call this as a class method, it works with the default error handler instead. iykyk.error( $error, [ arg1 [, arg2 ...] ] )β call this when you wanna report an error using the tree's currently definederror_handler. the only parameter that's guaranteed is an error string describing the issue β everything else is extra. there may be other arguments, and you can absolutely provide your own extra arguments in your subclass to pass along to your custom handler. slay.last_error()β if an error happened during the last behavior, this hands you back the error string. heads up: it's reset only byadd_child()andremove_child(). periodt.
π Default error handlers π
QUIETβ use this one when you want quiet error-handling. thelast_error()method will retrieve the error from the last operation, if there was one. and if an error occurs? the operation just returnsundefined. no drama, no noise.WARNDIE
that's genuinely the whole list, bestie βQUIET,WARN,DIE. the source only spells outQUIET, so i'm not gonna make stuff up about the other two. π
π EVENT HANDLING π
Tree provides for basic event handling. you may choose to register one or more callbacks that get called when the appropriate event occurs. the events are:
add_child
this event triggers as the last step in an add_child([$options], @nodes) call.
the parameters will be ( $self, @args ) where @args is the arguments passed into the add_child() call.
remove_child
this event triggers as the last step in an remove_child([$options], @nodes) call.
the parameters will be ( $self, @args ) where @args is the arguments passed into the remove_child() call.
value
this event triggers as the last step in a set_value() call.
the parameters will be ( $self, $old_value ) where $old_value is what the value was before it was changed. the new value can be accessed through $self->value().
π¦ Event handling methods π¦
add_event_handler( {$type => $callback [, $type => $callback, ... ]} )β you may choose to add event handlers for any known type. callbacks must be references to subroutines. they will be called in the order they are defined. no queue-jumping. πevent( $type, $actor, @args )β this triggers an event of type$type. all event handlers registered on$treewill be called with parameters of($actor, @args). then the parent gets notified of the event and its handlers get called, on up to the root. this is the iconic part: it lets you specify an event handler on the root and be guaranteed that it will fire every time the appropriate event occurs anywhere in the tree. main character energy fr fr. π
π NULL TREE π
if you call $self->parent on a root node, it will return a Tree::Null object. this is an implementation of the Null Object pattern optimized for usage with Tree. it will evaluate as false in every case (using overload), and all methods called on it will return a Tree::Null object. it's giving "yes, and?" forever. π
Notes
Tree::Nulldoes not inherit from Tree. this is so that all the methods will go throughAUTOLOADvs. the actual method.- however, calling
isa()on aTree::Nullobject will report that it is-a any object that is either Tree or in theTree::hierarchy. - the
Tree::Nullobject is a singleton. - the
Tree::Nullobject is defined, though. "I could not find a way to make it evaluate as undefined. That may be a good thing." β direct quote from the source, and honestly? mood. π
π CIRCULAR REFERENCES π
please q.v. Forest for more info on this topic.
β FAQ β
Which is the best tree processing module?
Tree::DAG_Node. more details: check SEE ALSO. π«Ά
How do I implement the visitor pattern?
the author deliberately chose to not implement the Visitor pattern as described by Gamma et al. given a sufficiently powerful traverse() and the capabilities of Perl, an explicit visitor object is almost always unneeded. if you want one, it's easy to write one yourself. here's a simple one the author wrote in 5 minutes:
package My::Visitor;
sub new {
my $class = shift;
my $opts = @_;
return bless {
tree => $opts->{tree},
action => $opts->{action},
}, $class;
}
sub visit {
my $self = shift;
my ($mode) = @_;
foreach my $node ( $self->{tree}->traverse( $mode ) ) {
$self->{action}->( $node );
}
}
Should I implement the visitor pattern?
No. you are better off using the walk_down($options) in Tree::DAG_Node method. sorry bestie, that's the verdict. π
πΈ SEE ALSO πΈ
Tree::Binaryβ lightweight.Tree::DAG_Nodeβ lightweight, and with a long list of methods.Tree::DAG_Node::Persistβ lightweight.Tree::Persistβ lightweight.Forestβ uses Moose.
Tree itself is also lightweight. tiny king behavior. π
π§ CODE COVERAGE π§
these statistics are as of V 1.01.
we use Devel::Cover to test the code coverage of our tests. below is the Devel::Cover report on the test suite of this module.
---------------------------- ------ ------ ------ ------ ------ ------ ------
File stmt bran cond sub pod time total
---------------------------- ------ ------ ------ ------ ------ ------ ------
blib/lib/Tree.pm 100.0 100.0 94.4 100.0 100.0 67.3 99.7
blib/lib/Tree/Binary.pm 96.4 95.0 100.0 100.0 100.0 10.7 96.7
blib/lib/Tree/Fast.pm 99.4 95.5 91.7 100.0 100.0 22.0 98.6
Total 98.9 96.8 94.9 100.0 100.0 100.0 98.5
---------------------------- ------ ------ ------ ------ ------ ------ ------
π ACKNOWLEDGEMENTS π
- Stevan Little for writing
Tree::Simple, upon which Tree is based.
Repository
https://github.com/ronsavage/Tree
π SUPPORT π
bugs should be reported via the CPAN bug tracker at
https://github.com/ronsavage/Tree/issues
π¦ AUTHORS π¦
Rob Kinyon <rob.kinyon@iinteractive.com>
Stevan Little <stevan.little@iinteractive.com>
thanks to Infinity Interactive for generously donating our time. π«Ά
co-maintenance since V 1.02 is by Ron Savage <rsavage@cpan.org>. uses of 'I' in previous versions is not me, but will be hereafter.
π COPYRIGHT AND LICENSE π
Copyright 2004, 2005 by Infinity Interactive, Inc.
this library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
and that's the whole page, bestie β no notes. this was Tree(3) from perl v5.42.0, dated 2025-07-25. go build some trees, you absolute icon. πβ¨π
π¦ where this page comes from
- fedora 43: perl-Tree 1.16-6.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms