1Tree::Simple(3) User Contributed Perl Documentation Tree::Simple(3)
2
3
4
6 Tree::Simple - A simple tree object
7
9 use Tree::Simple;
10
11 # make a tree root
12 my $tree = Tree::Simple->new("0", Tree::Simple->ROOT);
13
14 # explicitly add a child to it
15 $tree->addChild(Tree::Simple->new("1"));
16
17 # specify the parent when creating
18 # an instance and it adds the child implicitly
19 my $sub_tree = Tree::Simple->new("2", $tree);
20
21 # chain method calls
22 $tree->getChild(0)->addChild(Tree::Simple->new("1.1"));
23
24 # add more than one child at a time
25 $sub_tree->addChildren(
26 Tree::Simple->new("2.1"),
27 Tree::Simple->new("2.2")
28 );
29
30 # add siblings
31 $sub_tree->addSibling(Tree::Simple->new("3"));
32
33 # insert children a specified index
34 $sub_tree->insertChild(1, Tree::Simple->new("2.1a"));
35
36 # clean up circular references
37 $tree->DESTROY();
38
39 Alternately, to avoid calling Tree::Simple->new(...) just to add a
40 node:
41
42 use Tree::Simple;
43 use Data::TreeDumper; # Provides DumpTree().
44
45 # ---------------
46
47 my($root) = Tree::Simple->new('Root', Tree::Simple->ROOT);
48
49 $root->generateChild('Child 1.0');
50 $root->generateChild('Child 2.0');
51 $root->getChild(0)->generateChild('Grandchild 1.1');
52
53 print DumpTree($root);
54
55 $root->DESTROY;
56
58 This module in an fully object-oriented implementation of a simple
59 n-ary tree. It is built upon the concept of parent-child relationships,
60 so therefore every Tree::Simple object has both a parent and a set of
61 children (who themselves may have children, and so on). Every
62 Tree::Simple object also has siblings, as they are just the children of
63 their immediate parent.
64
65 It is can be used to model hierarchal information such as a file-
66 system, the organizational structure of a company, an object
67 inheritance hierarchy, versioned files from a version control system or
68 even an abstract syntax tree for use in a parser. It makes no
69 assumptions as to your intended usage, but instead simply provides the
70 structure and means of accessing and traversing said structure.
71
72 This module uses exceptions and a minimal Design By Contract style. All
73 method arguments are required unless specified in the documentation, if
74 a required argument is not defined an exception will usually be thrown.
75 Many arguments are also required to be of a specific type, for instance
76 the $parent argument to the constructor must be a Tree::Simple object
77 or an object derived from Tree::Simple, otherwise an exception is
78 thrown. This may seems harsh to some, but this allows me to have the
79 confidence that my code works as I intend, and for you to enjoy the
80 same level of confidence when using this module. Note however that this
81 module does not use any Exception or Error module, the exceptions are
82 just strings thrown with "die".
83
84 I consider this module to be production stable, it is based on a module
85 which has been in use on a few production systems for approx. 2 years
86 now with no issue. The only difference is that the code has been
87 cleaned up a bit, comments added and the thorough tests written for its
88 public release. I am confident it behaves as I would expect it to, and
89 is (as far as I know) bug-free. I have not stress-tested it under
90 extreme duress, but I do not so much intend for it to be used in that
91 type of situation. If this module cannot keep up with your Tree needs,
92 i suggest switching to one of the modules listed in the "OTHER TREE
93 MODULES" section below.
94
96 ROOT
97 This class constant serves as a placeholder for the root of our
98 tree. If a tree does not have a parent, then it is considered a
99 root.
100
102 Constructor
103 new ($node, $parent)
104 The constructor accepts two arguments a $node value and an optional
105 $parent. The $node value can be any scalar value (which includes
106 references and objects). The optional $parent value must be a
107 Tree::Simple object, or an object derived from Tree::Simple.
108 Setting this value implies that your new tree is a child of the
109 parent tree, and therefore adds it to the children of that parent.
110 If the $parent is not specified then its value defaults to ROOT.
111
112 Mutator Methods
113 setNodeValue ($node_value)
114 This sets the node value to the scalar $node_value, an exception is
115 thrown if $node_value is not defined.
116
117 setUID ($uid)
118 This allows you to set your own unique ID for this specific
119 Tree::Simple object. A default value derived from the hex address
120 of the object is provided for you, so use of this method is
121 entirely optional. It is the responsibility of the user to ensure
122 the value has uniqueness, all that is tested by this method is that
123 $uid is a true value (evaluates to true in a boolean context). For
124 even more information about the Tree::Simple UID see the "getUID"
125 method.
126
127 addChild ($tree)
128 This method accepts only Tree::Simple objects or objects derived
129 from Tree::Simple, an exception is thrown otherwise. This method
130 will append the given $tree to the end of the children list, and
131 set up the correct parent-child relationships. This method is set
132 up to return its invocant so that method call chaining can be
133 possible. Such as:
134
135 my $tree = Tree::Simple->new("root")->addChild(Tree::Simple->new("child one"));
136
137 Or the more complex:
138
139 my $tree = Tree::Simple->new("root")->addChild(
140 Tree::Simple->new("1.0")->addChild(
141 Tree::Simple->new("1.0.1")
142 )
143 );
144
145 generateChild ($scalar)
146 This method accepts a scalar and calls
147 addChild(Tree::Simple->new($scalar) ) purely to save you the effort
148 of needing to use "Tree::Simple->new(...)" as the parameter.
149
150 addChildren (@trees)
151 This method accepts an array of Tree::Simple objects, and adds them
152 to the children list. Like "addChild" this method will return its
153 invocant to allow for method call chaining.
154
155 insertChild ($index, $tree)
156 This method accepts a numeric $index and a Tree::Simple object
157 ($tree), and inserts the $tree into the children list at the
158 specified $index. This results in the shifting down of all
159 children after the $index. The $index is checked to be sure it is
160 the bounds of the child list, if it out of bounds an exception is
161 thrown. The $tree argument is verified to be a Tree::Simple or
162 Tree::Simple derived object, if this condition fails, an exception
163 is thrown.
164
165 insertChildren ($index, @trees)
166 This method functions much as insertChild does, but instead of
167 inserting a single Tree::Simple, it inserts an array of
168 Tree::Simple objects. It too bounds checks the value of $index and
169 type checks the objects in @trees just as "insertChild" does.
170
171 removeChild ($child | $index)>
172 Accepts two different arguments. If given a Tree::Simple object
173 ($child), this method finds that specific $child by comparing it
174 with all the other children until it finds a match. At which point
175 the $child is removed. If no match is found, and exception is
176 thrown. If a non-Tree::Simple object is given as the $child
177 argument, an exception is thrown.
178
179 This method also accepts a numeric $index and removes the child
180 found at that index within the list of children. The $index is
181 bounds checked, if this condition fail, an exception is thrown.
182
183 When a child is removed, it results in the shifting up of all
184 children after it, and the removed child is returned. The removed
185 child is properly disconnected from the tree and all its references
186 to its old parent are removed. However, in order to properly clean
187 up and circular references the removed child might have, it is
188 advised to call the "DESTROY" method. See the "CIRCULAR
189 REFERENCES" section for more information.
190
191 addSibling ($tree)
192 addSiblings (@trees)
193 insertSibling ($index, $tree)
194 insertSiblings ($index, @trees)
195 The "addSibling", "addSiblings", "insertSibling" and
196 "insertSiblings" methods pass along their arguments to the
197 "addChild", "addChildren", "insertChild" and "insertChildren"
198 methods of their parent object respectively. This eliminates the
199 need to overload these methods in subclasses which may have
200 specialized versions of the *Child(ren) methods. The one exceptions
201 is that if an attempt it made to add or insert siblings to the ROOT
202 of the tree then an exception is thrown.
203
204 NOTE: There is no "removeSibling" method as I felt it was probably a
205 bad idea. The same effect can be achieved by manual upwards traversal.
206
207 Accessor Methods
208 getNodeValue
209 This returns the value stored in the node field of the object.
210
211 getUID
212 This returns the unique ID associated with this particular tree.
213 This can be custom set using the "setUID" method, or you can just
214 use the default. The default is the hex-address extracted from the
215 stringified Tree::Simple object. This may not be a universally
216 unique identifier, but it should be adequate for at least the
217 current instance of your perl interpreter. If you need a UUID, one
218 can be generated with an outside module (there are
219 many to choose from on CPAN) and the "setUID" method (see
220 above).
221
222 getChild ($index)
223 This returns the child (a Tree::Simple object) found at the
224 specified $index. Note that we do use standard zero-based array
225 indexing.
226
227 getAllChildren
228 This returns an array of all the children (all Tree::Simple
229 objects). It will return an array reference in scalar context.
230
231 getSibling ($index)
232 getAllSiblings
233 Much like "addSibling" and "addSiblings", these two methods simply
234 call "getChild" and "getAllChildren" on the parent of the invocant.
235
236 See also </getSiblingCount>.
237
238 Warning: This method includes the invocant, so it is not really all
239 siblings but rather all children of the parent!
240
241 getSiblingCount
242 Returns 0 if the invocant is the root node. Otherwise returns the
243 count of siblings, which excludes the invocant.
244
245 See also </getAllSiblings>.
246
247 Warning: This differs from scalar(parent->getAllSiblings() ) just
248 above, which for some reason includes the invocant. I cannot change
249 getAllSiblings() now for a module first released in 2004.
250
251 getDepth
252 Returns a number representing the depth of the invocant within the
253 hierarchy of Tree::Simple objects.
254
255 NOTE: A "ROOT" tree has the depth of -1. This be because
256 Tree::Simple assumes that a root node will usually not contain
257 data, but just be an anchor for the data-containing branches. This
258 may not be intuitive in all cases, so I mention it here.
259
260 getParent
261 Returns the parent of the invocant, which could be either ROOT or a
262 Tree::Simple object.
263
264 getHeight
265 Returns a number representing the length of the longest path from
266 the current tree to the furthest leaf node.
267
268 getWidth
269 Returns the a number representing the breadth of the current tree,
270 basically it is a count of all the leaf nodes.
271
272 getChildCount
273 Returns the number of children the invocant contains.
274
275 getIndex
276 Returns the index of this tree within its sibling list. Returns -1
277 if the tree is the root.
278
279 Predicate Methods
280 isLeaf
281 Returns true (1) if the invocant does not have any children, false
282 (0) otherwise.
283
284 isRoot
285 Returns true (1) if the invocant has a "parent" of ROOT, returns
286 false (0) otherwise.
287
288 isFistChild
289 Returns 0 if the invocant is the root node.
290
291 Returns 1 if the invocant is the first child in the parental list
292 of children. Otherwise returns 0.
293
294 isLastChild
295 Returns 0 if the invocant is the root node.
296
297 Returns 1 if the invocant is the last child in the parental list of
298 children. Otherwise returns 0.
299
300 Recursive Methods
301 traverse ($func, ?$postfunc)
302 This method accepts two arguments a mandatory $func and an optional
303 $postfunc. If the argument $func is not defined then an exception
304 is thrown. If $func or $postfunc are not in fact CODE references
305 then an exception is thrown. The function $func is then applied
306 recursively to all the children of the invocant, or until $func
307 returns 'ABORT'. If given, the function $postfunc will be applied
308 to each child after the children of the child have been traversed.
309
310 Here is an example of a traversal function that will print out the
311 hierarchy as a tabbed in list.
312
313 $tree->traverse(sub {
314 my ($_tree) = @_;
315 my $tag = $_tree->getNodeValue();
316 print (("\t" x $_tree->getDepth()), $tag, "\n");
317 return 'ABORT' if 'foo' eq $tag;
318 });
319
320 Here is an example of a traversal function that will print out the
321 hierarchy in an XML-style format.
322
323 $tree->traverse(sub {
324 my ($_tree) = @_;
325 print ((' ' x $_tree->getDepth()),
326 '<', $_tree->getNodeValue(),'>',"\n");
327 },
328 sub {
329 my ($_tree) = @_;
330 print ((' ' x $_tree->getDepth()),
331 '</', $_tree->getNodeValue(),'>',"\n");
332 });
333
334 Note that aborting traverse is not recommended when using $postfunc
335 because post-function will not be called for any nodes after
336 aborting which might lead to less than predictable results.
337
338 size
339 Returns the total number of nodes in the current tree and all its
340 sub-trees.
341
342 height
343 This method has also been deprecated in favor of the "getHeight"
344 method above, it remains as an alias to "getHeight" for backwards
345 compatibility.
346
347 NOTE: This is also no longer a recursive method which get's it's
348 value on demand, but a value stored in the Tree::Simple object
349 itself, hopefully making it much more efficient and usable.
350
351 Visitor Methods
352 accept ($visitor)
353 It accepts either a Tree::Simple::Visitor object (which includes
354 classes derived
355 from Tree::Simple::Visitor), or an object who has the "visit"
356 method available
357 (tested with "$visitor->can('visit')"). If these qualifications
358 are not met,
359 and exception will be thrown. We then run the Visitor "visit"
360 method giving the
361 current tree as its argument.
362
363 I have also created a number of Visitor objects and packaged them
364 into the Tree::Simple::VisitorFactory.
365
366 Cloning Methods
367 Cloning a tree can be an extremely expensive operation for large trees,
368 so we provide two options for cloning, a deep clone and a shallow
369 clone.
370
371 When a Tree::Simple object is cloned, the node is deep-copied in the
372 following manner. If we find a normal scalar value (non-reference), we
373 simply copy it. If we find an object, we attempt to call "clone" on it,
374 otherwise we just copy the reference (since we assume the object does
375 not want to be cloned). If we find a SCALAR, REF reference we copy the
376 value contained within it. If we find a HASH or ARRAY reference we copy
377 the reference and recursively copy all the elements within it
378 (following these exact guidelines). We also do our best to assure that
379 circular references are cloned only once and connections restored
380 correctly. This cloning will not be able to copy CODE, RegExp and GLOB
381 references, as they are pretty much impossible to clone. We also do not
382 handle "tied" objects, and they will simply be copied as plain
383 references, and not re-"tied".
384
385 clone
386 The clone method does a full deep-copy clone of the object, calling
387 "clone" recursively on all its children. This does not call "clone"
388 on the parent tree however. Doing this would result in a slowly
389 degenerating spiral of recursive death, so it is not recommended
390 and therefore not implemented. What happens is that the tree
391 instance that "clone" is actually called upon is detached from the
392 tree, and becomes a root node, all if the cloned children are then
393 attached as children of that tree. I personally think this is more
394 intuitive then to have the cloning crawl back up the tree is not
395 what I think most people would expect.
396
397 cloneShallow
398 This method is an alternate option to the plain "clone" method.
399 This method allows the cloning of single Tree::Simple object while
400 retaining connections to the rest of the tree/hierarchy.
401
402 Misc. Methods
403 DESTROY
404 To avoid memory leaks through uncleaned-up circular references, we
405 implement the "DESTROY" method. This method will attempt to call
406 "DESTROY" on each of its children (if it has any). This will result
407 in a cascade of calls to "DESTROY" on down the tree. It also cleans
408 up it's parental relations as well.
409
410 Because of perl's reference counting scheme and how that interacts
411 with circular references, if you want an object to be properly
412 reaped you should manually call "DESTROY". This is especially
413 necessary if your object has any children. See the section on
414 "CIRCULAR REFERENCES" for more information.
415
416 fixDepth
417 Tree::Simple will manage the depth field for you using this method.
418 You should never need to call it on your own, however if you ever
419 did need to, here is it. Running this method will traverse your all
420 the sub-trees of the invocant, correcting the depth as it goes.
421
422 fixHeight
423 Tree::Simple will manage the height field for you using this
424 method. You should never need to call it on your own, however if
425 you ever did need to, here is it. Running this method will correct
426 the heights of the current tree and all ancestors heights too.
427
428 fixWidth
429 Tree::Simple will manage the width field for you using this method.
430 You should never need to call it on your own, however if you ever
431 did need to, here is it. Running this method will correct the
432 widths of the current tree and all ancestors widths too.
433
434 Private Methods
435 I would not normally document private methods, but in case you need to
436 subclass Tree::Simple, here they are.
437
438 _init ($node, $parent, $children)
439 This method is here largely to facilitate subclassing. This method
440 is called by new to initialize the object, where new has the
441 primary responsibility of creating the instance.
442
443 _setParent ($parent)
444 This method sets up the parental relationship. It is for internal
445 use only.
446
447 _setHeight ($child)
448 This method will set the height field based upon the height of the
449 given $child.
450
452 I have revised the model by which Tree::Simple deals with circular
453 references. In the past all circular references had to be manually
454 destroyed by calling DESTROY. The call to DESTROY would then call
455 DESTROY on all the children, and therefore cascade down the tree. This
456 however was not always what was needed, nor what made sense, so I have
457 now revised the model to handle things in what I feel is a more
458 consistent and sane way.
459
460 Circular references are now managed with the simple idea that the
461 parent makes the decisions for the child. This means that child-to-
462 parent references are weak, while parent-to-child references are
463 strong. So if a parent is destroyed it will force all the children to
464 detach from it, however, if a child is destroyed it will not be
465 detached from the parent.
466
467 Optional Weak References
468 By default, you are still required to call DESTROY in order for things
469 to happen. However I have now added the option to use weak references,
470 which alleviates the need for the manual call to DESTROY and allows
471 Tree::Simple to manage this automatically. This is accomplished with a
472 compile time setting like this:
473
474 use Tree::Simple 'use_weak_refs';
475
476 And from that point on Tree::Simple will use weak references to allow
477 for
478 reference counting to clean things up properly.
479
480 For those who are unfamiliar with weak references, and how they affect
481 the reference counts, here is a simple illustration. First is the
482 normal model that Tree::Simple uses:
483
484 +---------------+
485 | Tree::Simple1 |<---------------------+
486 +---------------+ |
487 | parent | |
488 | children |-+ |
489 +---------------+ | |
490 | |
491 | +---------------+ |
492 +->| Tree::Simple2 | |
493 +---------------+ |
494 | parent |-+
495 | children |
496 +---------------+
497
498 Here, Tree::Simple1 has a reference count of 2 (one for the original
499 variable it is assigned to, and one for the parent reference in
500 Tree::Simple2), and Tree::Simple2 has a reference count of 1 (for the
501 child reference in Tree::Simple1).
502
503 Now, with weak references:
504
505 +---------------+
506 | Tree::Simple1 |.......................
507 +---------------+ :
508 | parent | :
509 | children |-+ : <--[ weak reference ]
510 +---------------+ | :
511 | :
512 | +---------------+ :
513 +->| Tree::Simple2 | :
514 +---------------+ :
515 | parent |..
516 | children |
517 +---------------+
518
519 Now Tree::Simple1 has a reference count of 1 (for the variable it is
520 assigned to) and 1 weakened reference (for the parent reference in
521 Tree::Simple2). And Tree::Simple2 has a reference count of 1, just as
522 before.
523
525 None that I am aware of. The code is pretty thoroughly tested (see
526 "CODE COVERAGE" below) and is based on an (non-publicly released)
527 module which I had used in production systems for about 3 years without
528 incident. Of course, if you find a bug, let me know, and I will be sure
529 to fix it.
530
532 I use Devel::Cover to test the code coverage of my tests, below is the
533 Devel::Cover report on the test suite.
534
535 ---------------------------- ------ ------ ------ ------ ------ ------ ------
536 File stmt branch cond sub pod time total
537 ---------------------------- ------ ------ ------ ------ ------ ------ ------
538 Tree/Simple.pm 99.6 96.0 92.3 100.0 97.0 95.5 98.0
539 Tree/Simple/Visitor.pm 100.0 96.2 88.2 100.0 100.0 4.5 97.7
540 ---------------------------- ------ ------ ------ ------ ------ ------ ------
541 Total 99.7 96.1 91.1 100.0 97.6 100.0 97.9
542 ---------------------------- ------ ------ ------ ------ ------ ------ ------
543
545 I have written a number of other modules which use or augment this
546 module, they are describes below and available on CPAN.
547
548 Tree::Parser - A module for parsing formatted files into Tree::Simple
549 hierarchies
550 Tree::Simple::View - For viewing Tree::Simple hierarchies in various
551 output formats
552 Tree::Simple::VisitorFactory - Useful Visitor objects for Tree::Simple
553 objects
554 Tree::Binary - If you are looking for a binary tree, check this one out
555
556 Also, the author of Data::TreeDumper and I have worked together to make
557 sure that Tree::Simple and his module work well together. If you need
558 a quick and handy way to dump out a Tree::Simple hierarchy, this module
559 does an excellent job (and plenty more as well).
560
561 I have also recently stumbled upon some packaged distributions of
562 Tree::Simple for the various Unix flavors. Here are some links:
563
564 FreeBSD Port - <http://www.freshports.org/devel/p5-Tree-Simple/>
565 Debian Package -
566 <http://packages.debian.org/unstable/perl/libtree-simple-perl>
567 Linux RPM - <http://rpmpan.sourceforge.net/Tree.html>
568
570 There are a few other Tree modules out there, here is a quick
571 comparison between Tree::Simple and them. Obviously I am biased, so
572 take what I say with a grain of salt, and keep in mind, I wrote
573 Tree::Simple because I could not find a Tree module that suited my
574 needs. If Tree::Simple does not fit your needs, I recommend looking at
575 these modules. Please note that I am only listing Tree::* modules I am
576 familiar with here, if you think I have missed a module, please let me
577 know. I have also seen a few tree-ish modules outside of the Tree::*
578 namespace, but most of them are part of another distribution
579 (HTML::Tree, Pod::Tree, etc) and are likely specialized in purpose.
580
581 Tree::DAG_Node
582 This module seems pretty stable and very robust with a lot of
583 functionality. But it> only comes with 1 sophisticated test,
584 t/cut.and.paste.subtrees.t. While I am sure the author tested his
585 code, I would feel better if I was able to see that. The module is
586 approx. 3000 lines with POD, and 1,500 without the POD. The shear
587 depth and detail of the documentation and the ratio of code to
588 documentation is impressive, and not to be taken lightly. But given
589 that it is a well known fact that the likeliness of bugs increases
590 along side the size of the code, I do not feel comfortable with
591 large modules like this which have no tests.
592
593 All this said, I am not a huge fan of the API either, I prefer the
594 gender neutral approach in Tree::Simple to the mother/daughter
595 style of Tree::DAG_Node. I also feel very strongly that
596 Tree::DAG_Node is trying to do much more than makes sense in a
597 single module, and is offering too many ways to do the same or
598 similar things.
599
600 However, of all the Tree::* modules out there, Tree::DAG_Node seems
601 to be one of the favorites, so it may be worth investigating.
602
603 Tree::MultiNode
604 I am not very familiar with this module, however, I have heard some
605 good reviews of it, so I thought it deserved mention here. I
606 believe it is based upon C++ code found in the book Algorithms in
607 C++ by Robert Sedgwick. It uses a number of interesting ideas,
608 such as a ::Handle object to traverse the tree with (similar to
609 Visitors, but also seem to be to be kind of like a cursor).
610 However, like Tree::DAG_Node, it is somewhat lacking in tests and
611 has only 6 tests in its suite. It also has one glaring bug, which
612 is that there is currently no way to remove a child node.
613
614 Tree::Nary
615 It is a (somewhat) direct translation of the N-ary tree from the
616 GLIB library, and the API is based on that. GLIB is a C library,
617 which means this is a very C-ish API. That does not appeal to me,
618 it might to you, to each their own.
619
620 This module is similar in intent to Tree::Simple. It implements a
621 tree with n branches and has polymorphic node containers. It
622 implements much of the same methods as Tree::Simple and a few
623 others on top of that, but being based on a C library, is not very
624 OO. In most of the method calls the $self argument is not used and
625 the second argument $node is. Tree::Simple is a much more OO
626 module than Tree::Nary, so while they are similar in functionality
627 they greatly differ in implementation style.
628
629 Tree
630 This module is pretty old, it has not been updated since Oct. 31,
631 1999 and is still on version 0.01. It also seems to be (from the
632 limited documentation) a binary and a balanced binary tree,
633 Tree::Simple is an n-ary tree, and makes no attempt to balance
634 anything.
635
636 Tree::Ternary
637 This module is older than Tree, last update was Sept. 24th, 1999.
638 It seems to be a special purpose tree, for storing and accessing
639 strings, not general purpose like Tree::Simple.
640
641 Tree::Ternary_XS
642 This module is an XS implementation of the above tree type.
643
644 Tree::Trie
645 This too is a specialized tree type, it sounds similar to the
646 Tree::Ternary, but it much newer (latest release in 2003). It seems
647 specialized for the lookup and retrieval of information like a
648 hash.
649
650 Tree::M
651 Is a wrapper for a C++ library, whereas Tree::Simple is pure-perl.
652 It also seems to be a more specialized implementation of a tree,
653 therefore not really the same as Tree::Simple.
654
655 Tree::Fat
656 Is a wrapper around a C library, again Tree::Simple is pure-perl.
657 The author describes FAT-trees as a combination of a Tree and an
658 array. It looks like a pretty mean and lean module, and good if you
659 need speed and are implementing a custom data-store of some kind.
660 The author points out too that the module is designed for embedding
661 and there is not default embedding, so you cannot really use it
662 "out of the box".
663
665 Thanks to Nadim Ibn Hamouda El Khemir for making Data::TreeDumper work
666 with Tree::Simple.
667 Thanks to Brett Nuske for his idea for the "getUID" and "setUID"
668 methods.
669 Thanks to whomever submitted the memory leak bug to RT (#7512).
670 Thanks to Mark Thomas for his insight into how to best handle the
671 height and width properties without unnecessary recursion.
672 Thanks for Mark Lawrence for the &traverse post-func patch, tests and
673 docs.
674
676 Stevan Little, <stevan@iinteractive.com>
677
678 Rob Kinyon, <rob@iinteractive.com>
679
680 Ron Savage <ron@savage.net.au> has taken over maintenance as of V 1.19.
681
683 <https://github.com/ronsavage/Tree-Simple>.
684
686 Copyright 2004-2006 by Infinity Interactive, Inc.
687
688 <http://www.iinteractive.com>
689
690 This library is free software; you can redistribute it and/or modify it
691 under the same terms as Perl itself.
692
693
694
695perl v5.30.1 2020-01-30 Tree::Simple(3)