Merge lp:~noskcaj/ubuntu/vivid/libtree-perl/1.05 into lp:ubuntu/vivid/libtree-perl

Proposed by Jackson Doak
Status: Needs review
Proposed branch: lp:~noskcaj/ubuntu/vivid/libtree-perl/1.05
Merge into: lp:ubuntu/vivid/libtree-perl
Diff against target: 3109 lines (+1496/-1112)
27 files modified
Build.PL (+38/-34)
Changelog.ini (+70/-0)
Changes (+50/-17)
MANIFEST (+10/-7)
META.json (+72/-0)
META.yml (+47/-0)
Makefile.PL (+43/-0)
README (+49/-0)
debian/changelog (+6/-0)
lib/Tree.pm (+142/-101)
lib/Tree/Binary.pm (+0/-330)
lib/Tree/Binary2.pm (+330/-0)
lib/Tree/Fast.pm (+547/-543)
t/Tree/001_root_node.t (+7/-3)
t/Tree/003_child_node.t (+2/-1)
t/Tree/004_multiple_children.t (+2/-1)
t/Tree/005_multilevel_tree.t (+2/-1)
t/Tree/010_errors_addchild.t (+2/-1)
t/Tree/011_errors_removechild.t (+2/-1)
t/Tree/016_events.t (+2/-1)
t/Tree_Binary/000_binary_trees.t (+3/-2)
t/Tree_Binary/001_mirror.t (+1/-1)
t/Tree_Binary/002_clone.t (+4/-4)
t/lib/Tests.pm (+61/-0)
t/pod.t (+2/-2)
t/pod_coverage.t (+2/-2)
t/tests.pm (+0/-60)
To merge this branch: bzr merge lp:~noskcaj/ubuntu/vivid/libtree-perl/1.05
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Review via email: mp+244658@code.launchpad.net

Description of the change

New upstream release. Package might be better RMed though

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Thanks. Uploaded.

review: Approve

Unmerged revisions

4. By Jackson Doak

New upstream release.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Build.PL'
2--- Build.PL 2008-01-17 12:56:58 +0000
3+++ Build.PL 2014-12-12 23:08:52 +0000
4@@ -2,39 +2,43 @@
5
6 use 5.6.0;
7
8-use strict;
9 use warnings;
10
11-eval "use Tree::Binary;";
12-unless ($@) {
13- if ( (my $version = Tree::Binary->VERSION) <= 0.07 ) {
14- my $tree_binary_msg = "You currently have Tree::Binary version $version installed.\nThis distribution will install an incompatible Tree::Binary module on top of it.\nDo you wish for me to continue?";
15-
16- if ( !Module::Build->y_n( $tree_binary_msg, 'n' ) ) {
17- exit;
18- }
19- }
20-}
21-
22-my $build = Module::Build->new(
23- module_name => 'Tree',
24- license => 'perl',
25- requires => {
26- 'perl' => '5.6.0',
27- 'Scalar::Util' => '1.10',
28- },
29- build_requires => {
30- 'Scalar::Util' => '1.10',
31- 'Test::Deep' => '0.088',
32- 'Test::Exception' => '0.15',
33- 'Test::More' => '0.47',
34- 'Test::Warn' => '0.08',
35- },
36- create_makefile_pl => 'traditional',
37- recursive_test_files => 1,
38- add_to_cleanup => [
39- 'META.yml', '*.bak', '*.gz', 'Makefile.PL',
40- ],
41-);
42-
43-$build->create_build_script;
44+
45+Module::Build -> new
46+(
47+ dist_abstract => 'An N-ary tree',
48+ module_name => 'Tree',
49+ license => 'artistic_2',
50+ requires =>
51+ {
52+ perl => '5.6.0',
53+ Scalar::Util => 1.10,
54+ },
55+ configure_requires =>
56+ {
57+ Module::Build => 0.40,
58+ },
59+ build_requires =>
60+ {
61+ base => 0,
62+ constant => 0,
63+ Data::Dumper => 2.136,
64+ Exporter => 5.66,
65+ overload => 0,
66+ Scalar::Util => 1.10,
67+ strict => 0,
68+ Test::Deep => 0.088,
69+ Test::Exception => 0.15,
70+# Test::Pod => 1.45, # Make it optional. See t/pod.t
71+# Test::Pod::Coverage => 1.08, # Make it optional. See t/pod.t
72+ Test::More => 0.47,
73+ Test::Warn => 0.08,
74+ warnings => 0,
75+ },
76+ recursive_test_files => 1,
77+ add_to_cleanup =>
78+ [
79+ 'META.yml', '*.bak', '*.gz', 'Makefile.PL',
80+ ],
81+) -> create_build_script;
82
83=== added file 'Changelog.ini'
84--- Changelog.ini 1970-01-01 00:00:00 +0000
85+++ Changelog.ini 2014-12-12 23:08:52 +0000
86@@ -0,0 +1,70 @@
87+[Module]
88+Name=Tree
89+Changelog.Creator=Module::Metadata::Changes V 2.05
90+Changelog.Parser=Config::IniFiles V 2.78
91+
92+[V 1.05]
93+Date=2013-06-05T08:34:00
94+Comments= <<EOT
95+- No code changes.
96+- For pre-reqs base, constant and overload, which ship with Perl, set the version # to 0.
97+Requested by Andreas Mock. Actually, I should have done this with version 1.04.
98+- Rename CHANGES to Changes as per CPAN::Changes::Spec.
99+EOT
100+
101+[V 1.04]
102+Date=2012-11-08T12:38:00
103+Comments= <<EOT
104+- No code changes.
105+- For pre-reqs such as strict, warnings, etc, which ship with Perl, set the version # to 0.
106+Reported as RT#80663 by Father Chrysostomos for Tree::DAG_Node.
107+- Add README.
108+EOT
109+
110+[V 1.03]
111+Date=2012-11-02T09:34:00
112+Comments= <<EOT
113+- Rename Tree::Binary to Tree::Binary2 so it no longer clashes with the Tree::Binary shipped in the
114+Tree-Binary distro. MetaCPAN was getting confused, and automatically redirected links to this
115+module's Tree:Binary to the other one.
116+EOT
117+
118+[V 1.02]
119+Date=2012-10-04T12:10:00
120+Comments= <<EOT
121+- Ron Savage is now co-maint.
122+- Patch Tree::Fast's value() to accept a defained value so the node's value can be set with
123+$n -> value($new_value).
124+- Patch Tree::Fast's meta() to accept a hashref so metadata can be set with $n -> meta({key => value}),
125+as well as by directly accessing the internal hashref '_meta'.
126+- Patch t/Tree/001_root_node.t to test the above.
127+- Rename Changes to CHANGES.
128+- Use ini.report.pl (shipped with Module::Metadata::Changes) to add Changelog.ini to the distro.
129+- Reformat the dates in this file.
130+- Change lib/Tree/Fast.pm to Unix line endings.
131+- Clean up the POD.
132+- Re-work Makefile.PL rather than have Build.PL generate it.
133+- Update pre-reqs in Build.PL and Makefile.PL.
134+- Move t/tests.pm to t/lib/Tests.pm.
135+EOT
136+
137+[V 1.01]
138+Date=2007-10-18T12:00:00
139+Comments= <<EOT
140+- Fixed Changes file
141+- Right distro name.
142+- 1.00 release noted
143+- Cleaned up 5.6.0 -> 5.006
144+- Fix for RT# 16889 (clone broken for Tree::Binary)
145+- Patch submitted by HDP
146+- Fix for other miscellenous bugs
147+- Patch submitted by HDP
148+EOT
149+
150+[V 1.00]
151+Date=2005-11-08T12:00:00
152+Comments=- Initial release
153+
154+[V 0.99]
155+Date=2005-10-24T10:30:00
156+Comments=- Initial revision
157
158=== modified file 'Changes'
159--- Changes 2008-01-17 12:56:58 +0000
160+++ Changes 2014-12-12 23:08:52 +0000
161@@ -1,17 +1,50 @@
162-Revision history for Perl distribution Tree
163-
164-1.01 Oct 18, 2007
165- - Fixed Changes file
166- - Right distro name.
167- - 1.00 release noted
168- - Cleaned up 5.6.0 -> 5.006
169- - Fix for RT# 16889 (clone broken for Tree::Binary)
170- - Patch submitted by HDP
171- - Fix for other miscellenous bugs
172- - Patch submitted by HDP
173-
174-1.00 Nov 08, 2005
175- - Initial release
176-
177-0.99_01 Mon 24 Oct 2005 10:30:00
178- - Initial revision
179+Revision history for Perl distribution Tree.
180+
181+1.05 Wed Jun 5 08:34:00 2013
182+ - No code changes.
183+ - For pre-reqs base, constant and overload, which ship with Perl, set the version # to 0.
184+ Requested by Andreas Mock. Actually, I should have done this with version 1.04.
185+ - Rename CHANGES to Changes as per CPAN::Changes::Spec.
186+
187+1.04 Thu Nov 8 12:38:00 2012
188+ - No code changes.
189+ - For pre-reqs such as strict, warnings, etc, which ship with Perl, set the version # to 0.
190+ Reported as RT#80663 by Father Chrysostomos for Tree::DAG_Node.
191+ - Add README.
192+
193+1.03 Fri Nov 2 09:34:00 2012
194+ - Rename Tree::Binary to Tree::Binary2 so it no longer clashes with the Tree::Binary shipped in the
195+ Tree-Binary distro. MetaCPAN was getting confused, and automatically redirected links to this
196+ module's Tree:Binary to the other one.
197+
198+1.02 Thu Oct 4 12:10:00 2012
199+ - Ron Savage is now co-maint.
200+ - Patch Tree::Fast's value() to accept a defained value so the node's value can be set with
201+ $n -> value($new_value).
202+ - Patch Tree::Fast's meta() to accept a hashref so metadata can be set with $n -> meta({key => value}),
203+ as well as by directly accessing the internal hashref '_meta'.
204+ - Patch t/Tree/001_root_node.t to test the above.
205+ - Rename Changes to CHANGES.
206+ - Use ini.report.pl (shipped with Module::Metadata::Changes) to add Changelog.ini to the distro.
207+ - Reformat the dates in this file.
208+ - Change lib/Tree/Fast.pm to Unix line endings.
209+ - Clean up the POD.
210+ - Re-work Makefile.PL rather than have Build.PL generate it.
211+ - Update pre-reqs in Build.PL and Makefile.PL.
212+ - Move t/tests.pm to t/lib/Tests.pm.
213+
214+1.01 Thu Oct 18 12:00:00 2007
215+ - Fixed Changes file
216+ - Right distro name.
217+ - 1.00 release noted
218+ - Cleaned up 5.6.0 -> 5.006
219+ - Fix for RT# 16889 (clone broken for Tree::Binary)
220+ - Patch submitted by HDP
221+ - Fix for other miscellenous bugs
222+ - Patch submitted by HDP
223+
224+1.00 Tue Nov 08 12:00:00 2005
225+ - Initial release
226+
227+0.99 Mon Oct 24 10:30:00 2005
228+ - Initial revision
229
230=== modified file 'MANIFEST'
231--- MANIFEST 2008-01-17 12:56:58 +0000
232+++ MANIFEST 2014-12-12 23:08:52 +0000
233@@ -1,10 +1,17 @@
234 Build.PL
235+Changelog.ini
236 Changes
237+lib/Tree.pm
238+lib/Tree/Binary2.pm
239+lib/Tree/Fast.pm
240 Makefile.PL
241 MANIFEST This list of files
242-lib/Tree.pm
243-lib/Tree/Binary.pm
244-lib/Tree/Fast.pm
245+META.json
246+META.yml
247+README
248+t/lib/Tests.pm
249+t/pod.t
250+t/pod_coverage.t
251 t/Tree/000_interface.t
252 t/Tree/001_root_node.t
253 t/Tree/002_null_object.t
254@@ -26,7 +33,3 @@
255 t/Tree_Binary/001_mirror.t
256 t/Tree_Binary/002_clone.t
257 t/Tree_Fast/001_clone.t
258-t/pod.t
259-t/pod_coverage.t
260-t/tests.pm
261-META.yml
262
263=== added file 'META.json'
264--- META.json 1970-01-01 00:00:00 +0000
265+++ META.json 2014-12-12 23:08:52 +0000
266@@ -0,0 +1,72 @@
267+{
268+ "abstract" : "An N-ary tree",
269+ "author" : [
270+ "Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>",
271+ "Stevan Little E<lt>stevan.little@iinteractive.comE<gt>",
272+ "Co-maintenance since V 1.02 is by Ron Savage <rsavage@cpan.org>."
273+ ],
274+ "dynamic_config" : 1,
275+ "generated_by" : "Module::Build version 0.4005, CPAN::Meta::Converter version 2.120921",
276+ "license" : [
277+ "artistic_2"
278+ ],
279+ "meta-spec" : {
280+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
281+ "version" : "2"
282+ },
283+ "name" : "Tree",
284+ "prereqs" : {
285+ "build" : {
286+ "requires" : {
287+ "Data::Dumper" : "2.136",
288+ "Exporter" : "5.66",
289+ "Scalar::Util" : "1.1",
290+ "Test::Deep" : "0.088",
291+ "Test::Exception" : "0.15",
292+ "Test::More" : "0.47",
293+ "Test::Warn" : "0.08",
294+ "base" : "0",
295+ "constant" : "0",
296+ "overload" : "0",
297+ "strict" : "0",
298+ "warnings" : "0"
299+ }
300+ },
301+ "configure" : {
302+ "requires" : {
303+ "Module::Build" : "0.4"
304+ }
305+ },
306+ "runtime" : {
307+ "requires" : {
308+ "Scalar::Util" : "1.1",
309+ "perl" : "v5.6.0"
310+ }
311+ }
312+ },
313+ "provides" : {
314+ "Tree" : {
315+ "file" : "lib/Tree.pm",
316+ "version" : "1.05"
317+ },
318+ "Tree::Binary2" : {
319+ "file" : "lib/Tree/Binary2.pm",
320+ "version" : "1.05"
321+ },
322+ "Tree::Fast" : {
323+ "file" : "lib/Tree/Fast.pm",
324+ "version" : "1.05"
325+ },
326+ "Tree::Null" : {
327+ "file" : "lib/Tree/Fast.pm",
328+ "version" : 0
329+ }
330+ },
331+ "release_status" : "stable",
332+ "resources" : {
333+ "license" : [
334+ "http://www.perlfoundation.org/artistic_license_2_0"
335+ ]
336+ },
337+ "version" : "1.05"
338+}
339
340=== added file 'META.yml'
341--- META.yml 1970-01-01 00:00:00 +0000
342+++ META.yml 2014-12-12 23:08:52 +0000
343@@ -0,0 +1,47 @@
344+---
345+abstract: 'An N-ary tree'
346+author:
347+ - 'Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>'
348+ - 'Stevan Little E<lt>stevan.little@iinteractive.comE<gt>'
349+ - 'Co-maintenance since V 1.02 is by Ron Savage <rsavage@cpan.org>.'
350+build_requires:
351+ Data::Dumper: 2.136
352+ Exporter: 5.66
353+ Scalar::Util: 1.1
354+ Test::Deep: 0.088
355+ Test::Exception: 0.15
356+ Test::More: 0.47
357+ Test::Warn: 0.08
358+ base: 0
359+ constant: 0
360+ overload: 0
361+ strict: 0
362+ warnings: 0
363+configure_requires:
364+ Module::Build: 0.4
365+dynamic_config: 1
366+generated_by: 'Module::Build version 0.4005, CPAN::Meta::Converter version 2.120921'
367+license: artistic_2
368+meta-spec:
369+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
370+ version: 1.4
371+name: Tree
372+provides:
373+ Tree:
374+ file: lib/Tree.pm
375+ version: 1.05
376+ Tree::Binary2:
377+ file: lib/Tree/Binary2.pm
378+ version: 1.05
379+ Tree::Fast:
380+ file: lib/Tree/Fast.pm
381+ version: 1.05
382+ Tree::Null:
383+ file: lib/Tree/Fast.pm
384+ version: 0
385+requires:
386+ Scalar::Util: 1.1
387+ perl: v5.6.0
388+resources:
389+ license: http://www.perlfoundation.org/artistic_license_2_0
390+version: 1.05
391
392=== added file 'Makefile.PL'
393--- Makefile.PL 1970-01-01 00:00:00 +0000
394+++ Makefile.PL 2014-12-12 23:08:52 +0000
395@@ -0,0 +1,43 @@
396+use warnings;
397+
398+require 5.006000;
399+
400+use ExtUtils::MakeMaker;
401+
402+# ----------------------
403+
404+WriteMakefile
405+(
406+ ($] ge '5.005') ?
407+ (
408+ AUTHOR => 'Rob Kinyin (rkinyon@cpan.org)',
409+ ABSTRACT => 'Persist multiple trees in a single db table, preserving child order',
410+ ) : (),
411+ NAME => 'Tree',
412+ LICENSE => 'artistic_2',
413+ VERSION_FROM => 'lib/Tree.pm',
414+ PREREQ_PM =>
415+ {
416+ base => 0,
417+ constant => 0,
418+ Data::Dumper => 2.136,
419+ Exporter => 5.66,
420+ overload => 0,
421+ Scalar::Util => 1.10,
422+ strict => 0,
423+ Test::Deep => 0.088,
424+ Test::Exception => 0.15,
425+# Test::Pod => 1.45, # Make it optional. See t/pod.t
426+# Test::Pod::Coverage => 1.08, # Make it optional. See t/pod.t
427+ Test::More => 0.47,
428+ Test::Warn => 0.08,
429+ warnings => 0,
430+ },
431+ INSTALLDIRS => 'site',
432+ EXE_FILES => [],
433+ PL_FILES => {},
434+ test =>
435+ {
436+ TESTS => 't/*.t t/Tree_Binary/*.t t/Tree/*.t t/Tree_Fast/*.t',
437+ },
438+);
439
440=== added file 'README'
441--- README 1970-01-01 00:00:00 +0000
442+++ README 2014-12-12 23:08:52 +0000
443@@ -0,0 +1,49 @@
444+README file for Tree.
445+
446+See also: CHANGES and Changelog.ini.
447+
448+Warning: WinZip 8.1 and 9.0 both contain an 'accidental' bug which stops
449+them recognizing POSIX-style directory structures in valid tar files.
450+You are better off using a reliable tool such as InfoZip:
451+ftp://ftp.info-zip.org/pub/infozip/
452+
453+1 Installing from a Unix-like distro
454+------------------------------------
455+shell>gunzip Tree-1.03.tgz
456+shell>tar mxvf Tree-1.03.tar
457+
458+On Unix-like systems, assuming you have installed Module::Build V 0.25+:
459+
460+shell>perl Build.PL
461+shell>./Build
462+shell>./Build test
463+shell>./Build install
464+
465+On MS Windows-like systems, assuming you have installed Module::Build V 0.25+:
466+
467+shell>perl Build.PL
468+shell>perl Build
469+shell>perl Build test
470+shell>perl Build install
471+
472+Alternately, without Module::Build, you do this:
473+
474+Note: 'make' on MS Windows-like systems may be called 'nmake' or 'dmake'.
475+
476+shell>perl Makefile.PL
477+shell>make
478+shell>make test
479+shell>su (for Unix-like systems)
480+shell>make install
481+shell>exit (for Unix-like systems)
482+
483+On all systems:
484+
485+Run Tree.pm through your favourite pod2html translator.
486+
487+2 Installing from an ActiveState distro
488+---------------------------------------
489+shell>unzip Tree-1.03.zip
490+shell>ppm install --location=. Tree
491+shell>del Tree-1.03.ppd
492+shell>del PPM-Tree-1.03.tar.gz
493
494=== modified file 'debian/changelog'
495--- debian/changelog 2010-02-09 20:55:43 +0000
496+++ debian/changelog 2014-12-12 23:08:52 +0000
497@@ -1,3 +1,9 @@
498+libtree-perl (1.05-0ubuntu1) vivid; urgency=medium
499+
500+ * New upstream release.
501+
502+ -- Jackson Doak <noskcaj@ubuntu.com> Sat, 13 Dec 2014 08:10:01 +1100
503+
504 libtree-perl (1.01-0ubuntu2) lucid; urgency=low
505
506 * debian/control:
507
508=== modified file 'lib/Tree.pm'
509--- lib/Tree.pm 2008-01-17 12:56:58 +0000
510+++ lib/Tree.pm 2014-12-12 23:08:52 +0000
511@@ -5,7 +5,7 @@
512 use strict;
513 use warnings FATAL => 'all';
514
515-our $VERSION = '1.01';
516+our $VERSION = '1.05';
517
518 use Scalar::Util qw( blessed refaddr weaken );
519
520@@ -32,9 +32,9 @@
521 },
522 );
523
524-sub QUIET { return $error_handlers{ 'quiet' } }
525-sub WARN { return $error_handlers{ 'warn' } }
526-sub DIE { return $error_handlers{ 'die' } }
527+sub QUIET { return $error_handlers{ 'quiet' } }
528+sub WARN { return $error_handlers{ 'warn' } }
529+sub DIE { return $error_handlers{ 'die' } }
530
531 # The default error handler is quiet
532 my $ERROR_HANDLER = $error_handlers{ 'quiet' };
533@@ -381,7 +381,7 @@
534
535 =head1 NAME
536
537-Tree - an N-ary tree
538+Tree - An N-ary tree
539
540 =head1 SYNOPSIS
541
542@@ -419,6 +419,9 @@
543 value => sub { ... },
544 });
545
546+ my $old_default_error_handler = $tree->error_handler(Tree->DIE);
547+ my $old_object_error_handler = $tree->error_handler($tree->DIE);
548+
549 =head1 DESCRIPTION
550
551 This is meant to be a full-featured N-ary tree representation with
552@@ -428,39 +431,35 @@
553
554 =head1 METHODS
555
556-=head2 Constructor
557-
558-=over 4
559-
560-=item B<new([$value])>
561-
562-This will return a Tree object. It will accept one parameter which, if passed,
563-will become the value (accessible by C<value()>). All other parameters will be
564+=head2 Constructors
565+
566+=head2 new([$value])
567+
568+Here, [] indicate an optional parameter.
569+
570+This will return a C<Tree> object. It will accept one parameter which, if passed,
571+will become the I<value> (accessible by C<value()>). All other parameters will be
572 ignored.
573
574-If you call C<$tree-E<gt>new([$value])>, it will instead call C<clone()>, then set
575-the value of the clone to $value.
576+If you call C<< $tree->new([$value]) >>, it will instead call C<clone()>, then set
577+the I<value> of the clone to $value.
578
579-=item B<clone()>
580+=head2 clone()
581
582 This will return a clone of C<$tree>. The clone will be a root tree, but all
583 children will be cloned.
584
585-If you call L<Tree-E<gt>clone([$value])>, it will instead call C<new()>.
586+If you call C<< Tree->clone([$value]) >>, it will instead call C<new($value)>.
587
588 B<NOTE:> the value is merely a shallow copy. This means that all references
589 will be kept.
590
591-=back
592-
593 =head2 Behaviors
594
595-=over 4
596-
597-=item B<add_child([$options], @nodes)>
598+=head2 add_child([$options], @nodes)
599
600 This will add all the C<@nodes> as children of C<$tree>. $options is a optional
601-unblessed hashref that specifies options for add_child(). The optional
602+unblessed hashref that specifies options for C<add_child()>. The optional
603 parameters are:
604
605 =over 4
606@@ -469,11 +468,17 @@
607
608 This specifies the index to add C<@nodes> at. If specified, this will be passed
609 into splice(). The only exceptions are if this is 0, it will act as an
610-unshift(). If it is unset or undefined, it will act as a push().
611+unshift(). If it is unset or undefined, it will act as a push(). Lastly, if it is out of range
612+(too negative or too big [beyond the number of children]) the child is not added, and an error msg
613+will be available in L</last_error()>.
614
615 =back
616
617-=item B<remove_child([$options], @nodes)>
618+add_child() resets last_error() upon entry.
619+
620+=head2 remove_child([$options], @nodes)
621+
622+Here, [] indicate an optional parameter.
623
624 This will remove all the C<@nodes> from the children of C<$tree>. You can either
625 pass in the actual child object you wish to remove, the index of the child you
626@@ -482,16 +487,23 @@
627 $options is a optional unblessed hashref that specifies parameters for
628 remove_child(). Currently, no parameters are used.
629
630-=item B<mirror()>
631+remove_child() resets last_error() upon entry.
632+
633+=head2 mirror()
634
635 This will modify the tree such that it is a mirror of what it was before. This
636 means that the order of all children is reversed.
637
638 B<NOTE>: This is a destructive action. It I<will> modify the tree's internal
639 structure. If you wish to get a mirror, yet keep the original tree intact, use
640-C<my $mirror = $tree-E<gt>clone-E<gt>mirror;>
641-
642-=item B<traverse( [$order] )>
643+C<< my $mirror = $tree->clone->mirror >>.
644+
645+mirror() does not reset last_error() because it (mirror() ) is implemented in L<Tree::Fast>,
646+which has no error handling.
647+
648+=head2 traverse([$order])
649+
650+Here, [] indicate an optional parameter.
651
652 This will return a list of the nodes in the given traversal order. The default
653 traversal order is pre-order.
654@@ -500,65 +512,63 @@
655
656 =over 4
657
658-=item * Pre-order (aka Prefix traversal)
659+=item * Pre-order
660
661 This will return the node, then the first sub tree in pre-order traversal,
662 then the next sub tree, etc.
663
664-Use C<$tree-E<gt>PRE_ORDER> as the C<$order>.
665+Use C<< $tree->PRE_ORDER >> as the C<$order>.
666
667-=item * Post-order (aka Prefix traversal)
668+=item * Post-order
669
670 This will return the each sub-tree in post-order traversal, then the node.
671
672-Use C<$tree-E<gt>POST_ORDER> as the C<$order>.
673+Use C<< $tree->POST_ORDER >> as the C<$order>.
674
675-=item * Level-order (aka Prefix traversal)
676+=item * Level-order
677
678 This will return the node, then the all children of the node, then all
679 grandchildren of the node, etc.
680
681-Use C<$tree-E<gt>LEVEL_ORDER> as the C<$order>.
682-
683-=back
684-
685-=back
686-
687-All behaviors will reset last_error().
688+Use C<< $tree->LEVEL_ORDER >> as the C<$order>.
689+
690+=back
691+
692+traverse() does not reset last_error() because it (traverse() ) is implemented in L<Tree::Fast>,
693+which has no error handling.
694
695 =head2 State Queries
696
697-=over 4
698-
699-=item * B<is_root()>
700-
701-This will return true is C<$tree> has no parent and false otherwise.
702-
703-=item * B<is_leaf()>
704-
705-This will return true is C<$tree> has no children and false otherwise.
706-
707-=item * B<has_child(@nodes)>
708-
709-This will return true is C<$tree> has each of the C<@nodes> as a child.
710+=head2 is_root()
711+
712+This will return true if C<$tree> has no parent and false otherwise.
713+
714+=head2 is_leaf()
715+
716+This will return true if C<$tree> has no children and false otherwise.
717+
718+=head2 has_child(@nodes)
719+
720+This will return true if C<$tree> has each of the C<@nodes> as a child.
721 Otherwise, it will return false.
722
723-=item * B<get_index_for(@nodes)>
724-
725-This will return the index into the children list for each of the C<@nodes>
726+The test to see if a node is in the tree uses refaddr() from L<Scalar::Util>, not the I<value> of the node.
727+This means C<@nodes> must be an array of C<Tree> objects.
728+
729+=head2 get_index_for(@nodes)
730+
731+This will return the index into the children list of C<$tree> for each of the C<@nodes>
732 passed in.
733
734-=back
735-
736 =head2 Accessors
737
738-=over 4
739-
740-=item * B<parent()>
741+=head2 parent()
742
743 This will return the parent of C<$tree>.
744
745-=item * B<children( [ $idx, [$idx, ..] ] )>
746+=head2 children( [ $idx, [$idx, ..] ] )
747+
748+Here, [] indicate optional parameters.
749
750 This will return the children of C<$tree>. If called in list context, it will
751 return all the children. If called in scalar context, it will return the
752@@ -568,22 +578,22 @@
753 children in the order you asked for them. This is very much like an
754 arrayslice.
755
756-=item * B<root()>
757+=head2 root()
758
759 This will return the root node of the tree that C<$tree> is in. The root of
760 the root node is itself.
761
762-=item * B<height()>
763+=head2 height()
764
765 This will return the height of C<$tree>. A leaf has a height of 1. A parent
766 has a height of its tallest child, plus 1.
767
768-=item * B<width()>
769+=head2 width()
770
771 This will return the width of C<$tree>. A leaf has a width of 1. A parent has
772 a width equal to the sum of all the widths of its children.
773
774-=item * B<depth()>
775+=head2 depth()
776
777 This will return the depth of C<$tree>. A root has a depth of 0. A child has
778 the depth of its parent, plus 1.
779@@ -591,21 +601,25 @@
780 This is the distance from the root. It's useful for things like
781 pretty-printing the tree.
782
783-=item * B<size()>
784+=head2 size()
785
786 This will return the number of nodes within C<$tree>. A leaf has a size of 1.
787 A parent has a size equal to the 1 plus the sum of all the sizes of its
788 children.
789
790-=item * B<value()>
791+=head2 value()
792
793 This will return the value stored in the node.
794
795-=item * B<set_value([$value])>
796-
797-This will set the value stored in the node to $value, then return $self.
798-
799-=item * B<meta()>
800+=head2 set_value([$value])
801+
802+Here, [] indicate an optional parameter.
803+
804+This will set the I<value> stored in the node to $value, then return $self.
805+
806+If C<$value> is not provided, undef is used.
807+
808+=head2 meta()
809
810 This will return a hashref that can be used to store whatever metadata the
811 client wishes to store. For example, L<Tree::Persist::DB> uses this to store
812@@ -616,8 +630,6 @@
813 this, using a unique key for each persistence layer associated with that tree.
814 This will help prevent clobbering of metadata.
815
816-=back
817-
818 =head1 ERROR HANDLING
819
820 Describe what the default error handlers do and what a custom error handler is
821@@ -625,9 +637,7 @@
822
823 =head2 Error-related methods
824
825-=over 4
826-
827-=item * B<error_handler( [ $handler ] )>
828+=head2 error_handler( [ $handler ] )
829
830 This will return the current error handler for the tree. If a value is passed
831 in, then it will be used to set the error handler for the tree.
832@@ -635,19 +645,17 @@
833 If called as a class method, this will instead work with the default error
834 handler.
835
836-=item * B<error( $error, [ arg1 [, arg2 ...] ] )>
837+=head2 error( $error, [ arg1 [, arg2 ...] ] )
838
839 Call this when you wish to report an error using the currently defined
840 error_handler for the tree. The only guaranteed parameter is an error string
841 describing the issue. There may be other arguments, and you may certainly
842 provide other arguments in your subclass to be passed to your custom handler.
843
844-=item * B<last_error()>
845+=head2 last_error()
846
847 If an error occurred during the last behavior, this will return the error
848-string. It is reset only when a behavior is called.
849-
850-=back
851+string. It is reset only by add_child() and remove_child().
852
853 =head2 Default error handlers
854
855@@ -656,7 +664,7 @@
856 =item QUIET
857
858 Use this error handler if you want to have quiet error-handling. The
859-last_error method will retrieve the error from the last operation, if there
860+L</last_error()> method will retrieve the error from the last operation, if there
861 was one. If an error occurs, the operation will return undefined.
862
863 =item WARN
864@@ -667,7 +675,7 @@
865
866 =head1 EVENT HANDLING
867
868-Forest provides for basic event handling. You may choose to register one or
869+Tree provides for basic event handling. You may choose to register one or
870 more callbacks to be called when the appropriate event occurs. The events
871 are:
872
873@@ -675,14 +683,14 @@
874
875 =item * add_child
876
877-This event will trigger as the last step in an L<add_child()> call.
878+This event will trigger as the last step in an L</add_child([$options], @nodes)> call.
879
880 The parameters will be C<( $self, @args )> where C<@args> is the arguments
881 passed into the add_child() call.
882
883 =item * remove_child
884
885-This event will trigger as the last step in an L<remove_child()> call.
886+This event will trigger as the last step in an L</remove_child([$options], @nodes)> call.
887
888 The parameters will be C<( $self, @args )> where C<@args> is the arguments
889 passed into the remove_child() call.
890@@ -699,14 +707,12 @@
891
892 =head2 Event handling methods
893
894-=over 4
895-
896-=item * B<add_event_handler( $type => $callback [, $type => $callback, ... ])>
897+=head2 add_event_handler( {$type => $callback [, $type => $callback, ... ]} )
898
899 You may choose to add event handlers for any known type. Callbacks must be
900 references to subroutines. They will be called in the order they are defined.
901
902-=item * B<event( $type, $actor, @args )>
903+=head2 event( $type, $actor, @args )
904
905 This will trigger an event of type C<$type>. All event handlers registered on
906 C<$tree> will be called with parameters of C<($actor, @args)>. Then, the
907@@ -716,14 +722,12 @@
908 This allows you specify an event handler on the root and be guaranteed that it
909 will fire every time the appropriate event occurs anywhere in the tree.
910
911-=back
912-
913 =head1 NULL TREE
914
915 If you call C<$self-E<gt>parent> on a root node, it will return a Tree::Null
916 object. This is an implementation of the Null Object pattern optimized for
917 usage with L<Tree>. It will evaluate as false in every case (using
918-L<overload>) and all methods called on it will return a Tree::Null object.
919+I<overload>) and all methods called on it will return a Tree::Null object.
920
921 =head2 Notes
922
923@@ -754,11 +758,13 @@
924
925 Please q.v. L<Forest> for more info on this topic.
926
927-=head1 WHAT'S NOT HERE
928-
929-=over 4
930-
931-=item * The Visitor pattern
932+=head1 FAQ
933+
934+=head2 Which is the best tree processing module?
935+
936+L<Tree::DAG_Node>. More details: L</SEE ALSO>.
937+
938+=head2 How do I implement the visitor pattern?
939
940 I have deliberately chosen to not implement the Visitor pattern as described
941 by Gamma et al. Given a sufficiently powerful C<traverse()> and Perl's
942@@ -787,10 +793,42 @@
943 }
944 }
945
946+=head2 Should I implement the visitor pattern?
947+
948+No. You're better off using the L<Tree::DAG_Node/walk_down($options)> method.
949+
950+=head1 SEE ALSO
951+
952+=over 4
953+
954+=item o L<Tree::Binary>
955+
956+Lightweight.
957+
958+=item o L<Tree::DAG_Node>
959+
960+Lightweight, and with a long list of methods.
961+
962+=item o L<Tree::DAG_Node::Persist>
963+
964+Lightweight.
965+
966+=item o L<Tree::Persist>
967+
968+Lightweight.
969+
970+=item o L<Forest>
971+
972+Uses L<Moose>.
973+
974 =back
975
976+C<Tree> itself is also lightweight.
977+
978 =head1 CODE COVERAGE
979
980+These statistics are as of V 1.01.
981+
982 We use L<Devel::Cover> to test the code coverage of our tests. Below is the
983 L<Devel::Cover> report on this module's test suite.
984
985@@ -824,6 +862,9 @@
986
987 Thanks to Infinity Interactive for generously donating our time.
988
989+Co-maintenance since V 1.02 is by Ron Savage <rsavage@cpan.org>.
990+Uses of 'I' in previous versions is not me, but will be hereafter.
991+
992 =head1 COPYRIGHT AND LICENSE
993
994 Copyright 2004, 2005 by Infinity Interactive, Inc.
995@@ -831,6 +872,6 @@
996 L<http://www.iinteractive.com>
997
998 This library is free software; you can redistribute it and/or modify it under
999-the same terms as Perl itself.
1000+the same terms as Perl itself.
1001
1002 =cut
1003
1004=== removed file 'lib/Tree/Binary.pm'
1005--- lib/Tree/Binary.pm 2008-01-17 12:56:58 +0000
1006+++ lib/Tree/Binary.pm 1970-01-01 00:00:00 +0000
1007@@ -1,330 +0,0 @@
1008-package Tree::Binary;
1009-
1010-use 5.006;
1011-
1012-use strict;
1013-use warnings FATAL => 'all';
1014-
1015-use Scalar::Util qw( blessed );
1016-
1017-use base qw( Tree );
1018-
1019-our $VERSION = '1.01';
1020-
1021-sub _init {
1022- my $self = shift;
1023- $self->SUPER::_init( @_ );
1024-
1025- # Make this class a complete binary tree,
1026- # filling in with Tree::Null as appropriate.
1027- $self->{_children}->[$_] = $self->_null
1028- for 0 .. 1;
1029-
1030- return $self;
1031-}
1032-
1033-sub left {
1034- my $self = shift;
1035- return $self->_set_get_child( 0, @_ );
1036-}
1037-
1038-sub right {
1039- my $self = shift;
1040- return $self->_set_get_child( 1, @_ );
1041-}
1042-
1043-sub _set_get_child {
1044- my $self = shift;
1045- my $index = shift;
1046-
1047- if ( @_ ) {
1048- my $node = shift;
1049- $node = $self->_null unless $node;
1050-
1051- my $old = $self->children->[$index];
1052- $self->children->[$index] = $node;
1053-
1054- if ( $node ) {
1055- $node->_set_parent( $self );
1056- $node->_set_root( $self->root );
1057- $node->_fix_depth;
1058- }
1059-
1060- if ( $old ) {
1061- $old->_set_parent( $old->_null );
1062- $old->_set_root( $old->_null );
1063- $old->_fix_depth;
1064- }
1065-
1066- $self->_fix_height;
1067- $self->_fix_width;
1068-
1069- return $self;
1070- }
1071- else {
1072- return $self->children->[$index];
1073- }
1074-}
1075-
1076-sub _clone_children {
1077- my ($self, $clone) = @_;
1078-
1079- @{ $clone->{_children} } = ();
1080- $clone->add_child({}, map { $_->clone } @{ $self->{_children} });
1081-}
1082-
1083-sub children {
1084- my $self = shift;
1085- if ( @_ ) {
1086- my @idx = @_;
1087- return @{$self->{_children}}[@idx];
1088- }
1089- else {
1090- if ( caller->isa( __PACKAGE__ ) || $self->isa( scalar(caller) ) ) {
1091- return wantarray ? @{$self->{_children}} : $self->{_children};
1092- }
1093- else {
1094- return grep { $_ } @{$self->{_children}};
1095- }
1096- }
1097-}
1098-
1099-use constant IN_ORDER => 4;
1100-
1101-# One of the things we have to do in a traversal is to remove all of the
1102-# Tree::Null elements that are appended to the tree to make this a complete
1103-# binary tree. The user isn't going to expect them, because they're an
1104-# internal nicety.
1105-
1106-sub traverse {
1107- my $self = shift;
1108- my $order = shift;
1109- $order = $self->PRE_ORDER unless $order;
1110-
1111- if ( wantarray ) {
1112- if ( $order == $self->IN_ORDER ) {
1113- return grep { $_ } (
1114- $self->left->traverse( $order ),
1115- $self,
1116- $self->right->traverse( $order ),
1117- );
1118- }
1119- else {
1120- return grep { $_ } $self->SUPER::traverse( $order );
1121- }
1122- }
1123- else {
1124- my $closure;
1125-
1126- if ( $order eq $self->IN_ORDER ) {
1127- my @list = $self->traverse( $order );
1128-
1129- $closure = sub {
1130- return unless @list;
1131- return shift @list;
1132- };
1133- }
1134- elsif ( $order eq $self->PRE_ORDER ) {
1135- my $next_node = $self;
1136- my @stack = ( $self );
1137- my @next_meth = ( 0 );
1138-
1139- my @meths = qw( left right );
1140- $closure = sub {
1141- my $node = $next_node;
1142- return unless $node;
1143- $next_node = undef;
1144-
1145- while ( @stack && !$next_node ) {
1146- while ( @next_meth && $next_meth[0] == 2 ) {
1147- shift @stack;
1148- shift @next_meth;
1149- }
1150-
1151- if ( @stack ) {
1152- my $meth = $meths[ $next_meth[0]++ ];
1153- $next_node = $stack[0]->$meth;
1154- next unless $next_node;
1155- unshift @stack, $next_node;
1156- unshift @next_meth, 0;
1157- }
1158- }
1159-
1160- return $node;
1161- };
1162- }
1163- elsif ( $order eq $self->POST_ORDER ) {
1164- my @list = $self->traverse( $order );
1165-
1166- $closure = sub {
1167- return unless @list;
1168- return shift @list;
1169- };
1170- #my @stack = ( $self );
1171- #my @next_idx = ( 0 );
1172- #while ( @{ $stack[0]->{_children} } ) {
1173- # unshift @stack, $stack[0]->{_children}[0];
1174- # unshift @next_idx, 0;
1175- #}
1176- #
1177- #$closure = sub {
1178- # my $node = $stack[0] || return;
1179- #
1180- # shift @stack; shift @next_idx;
1181- # $next_idx[0]++;
1182- #
1183- # while ( @stack && exists $stack[0]->{_children}[ $next_idx[0] ] ) {
1184- # unshift @stack, $stack[0]->{_children}[ $next_idx[0] ];
1185- # unshift @next_idx, 0;
1186- # }
1187- #
1188- # return $node;
1189- #};
1190- }
1191- elsif ( $order eq $self->LEVEL_ORDER ) {
1192- my @nodes = ($self);
1193- $closure = sub {
1194- my $node = shift @nodes;
1195- return unless $node;
1196- push @nodes, grep { $_ } @{$node->{_children}};
1197- return $node;
1198- };
1199- }
1200- else {
1201- return $self->error( "traverse(): '$order' is an illegal traversal order" );
1202- }
1203-
1204- return $closure;
1205- }
1206-}
1207-
1208-1;
1209-__END__
1210-
1211-=head1 NAME
1212-
1213-Tree::Binary - An implementation of a binary tree
1214-
1215-=head1 SYNOPSIS
1216-
1217- my $tree = Tree::Binary->new( 'root' );
1218-
1219- my $left = Tree::Binary->new( 'left' );
1220- $tree->left( $left );
1221-
1222- my $right = Tree::Binary->new( 'left' );
1223- $tree->right( $right );
1224-
1225- my $right_child = $tree->right;
1226-
1227- $tree->right( undef ); # Unset the right child.
1228-
1229- my @nodes = $tree->traverse( $tree->POST_ORDER );
1230-
1231- my $traversal = $tree->traverse( $tree->IN_ORDER );
1232- while ( my $node = $traversal->() ) {
1233- # Do something with $node here
1234- }
1235-
1236-=head1 DESCRIPTION
1237-
1238-This is an implementation of a binary tree. This class inherits from L<Tree>,
1239-which is an N-ary tree implemenation. Because of this, this class actually
1240-provides an implementation of a complete binary tree vs. a sparse binary tree.
1241-The empty nodes are instances of Tree::Null, which is described in L<Tree>.
1242-This should have no effect on your usage of this class.
1243-
1244-=head1 METHODS
1245-
1246-In addition to the methods provided by L<Tree>, the following items are
1247-provided or overriden.
1248-
1249-=over 4
1250-
1251-=item * C<left([$child])> / C<right([$child])>
1252-
1253-These access the left and right children, respectively. They are mutators,
1254-which means that their behavior changes depending on if you pass in a value.
1255-
1256-If you do not pass in any parameters, then it will act as a getter for the
1257-specific child, return the child (if set) or undef (if not).
1258-
1259-If you pass in a child, it will act as a setter for the specific child,
1260-setting the child to the passed-in value and returning the $tree. (Thus, this
1261-method chains.)
1262-
1263-If you wish to unset the child, do C<$treeE<gt>left( undef );>
1264-
1265-=item * C<children()>
1266-
1267-This will return the children of the tree.
1268-
1269-B<NOTE:> There will be two children, always. Tree::Binary implements a
1270-complete binary tree, filling in missing children with Tree::Null objects.
1271-(Please see L<Tree::Fast> for more information on Tree::Null.)
1272-
1273-=item * B<traverse( [$order] )>
1274-
1275-When called in list context (C<my @traversal = $tree-E<gt>traverse()>), this will
1276-return a list of the nodes in the given traversal order. When called in scalar
1277-context (C<my $traversal = $tree-E<gt>traverse()>), this will return a closure
1278-that will, over successive calls, iterate over the nodes in the given
1279-traversal order. When finished it will return false.
1280-
1281-The default traversal order is pre-order.
1282-
1283-In addition to the traversal orders provided by L<Tree>, Tree::Binary provides
1284-in-order traversals.
1285-
1286-=over 4
1287-
1288-=item * In-order
1289-
1290-This will return the result of an in-order traversal on the left node (if
1291-any), then the node, then the result of an in-order traversal on the right
1292-node (if any).
1293-
1294-=back
1295-
1296-=back
1297-
1298-B<NOTE:> You have access to all the methods provided by L<Tree>, but it is not
1299-recommended that you use many of them, unless you know what you're doing. This
1300-list includes C<add_child()> and C<remove_child()>.
1301-
1302-=head1 TODO
1303-
1304-=over 4
1305-
1306-=item * Make in-order closure traversal work iteratively
1307-
1308-=item * Make post-order closure traversal work iteratively
1309-
1310-=back
1311-
1312-=head1 CODE COVERAGE
1313-
1314-Please see the relevant sections of L<Tree>.
1315-
1316-=head1 SUPPORT
1317-
1318-Please see the relevant sections of L<Tree>.
1319-
1320-=head1 AUTHORS
1321-
1322-Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>
1323-
1324-Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
1325-
1326-Thanks to Infinity Interactive for generously donating our time.
1327-
1328-=head1 COPYRIGHT AND LICENSE
1329-
1330-Copyright 2004, 2005 by Infinity Interactive, Inc.
1331-
1332-L<http://www.iinteractive.com>
1333-
1334-This library is free software; you can redistribute it and/or modify it under
1335-the same terms as Perl itself.
1336-
1337-=cut
1338
1339=== added file 'lib/Tree/Binary2.pm'
1340--- lib/Tree/Binary2.pm 1970-01-01 00:00:00 +0000
1341+++ lib/Tree/Binary2.pm 2014-12-12 23:08:52 +0000
1342@@ -0,0 +1,330 @@
1343+package Tree::Binary2;
1344+
1345+use 5.006;
1346+
1347+use strict;
1348+use warnings FATAL => 'all';
1349+
1350+use Scalar::Util qw( blessed );
1351+
1352+use base qw( Tree );
1353+
1354+our $VERSION = '1.05';
1355+
1356+sub _init {
1357+ my $self = shift;
1358+ $self->SUPER::_init( @_ );
1359+
1360+ # Make this class a complete binary tree,
1361+ # filling in with Tree::Null as appropriate.
1362+ $self->{_children}->[$_] = $self->_null
1363+ for 0 .. 1;
1364+
1365+ return $self;
1366+}
1367+
1368+sub left {
1369+ my $self = shift;
1370+ return $self->_set_get_child( 0, @_ );
1371+}
1372+
1373+sub right {
1374+ my $self = shift;
1375+ return $self->_set_get_child( 1, @_ );
1376+}
1377+
1378+sub _set_get_child {
1379+ my $self = shift;
1380+ my $index = shift;
1381+
1382+ if ( @_ ) {
1383+ my $node = shift;
1384+ $node = $self->_null unless $node;
1385+
1386+ my $old = $self->children->[$index];
1387+ $self->children->[$index] = $node;
1388+
1389+ if ( $node ) {
1390+ $node->_set_parent( $self );
1391+ $node->_set_root( $self->root );
1392+ $node->_fix_depth;
1393+ }
1394+
1395+ if ( $old ) {
1396+ $old->_set_parent( $old->_null );
1397+ $old->_set_root( $old->_null );
1398+ $old->_fix_depth;
1399+ }
1400+
1401+ $self->_fix_height;
1402+ $self->_fix_width;
1403+
1404+ return $self;
1405+ }
1406+ else {
1407+ return $self->children->[$index];
1408+ }
1409+}
1410+
1411+sub _clone_children {
1412+ my ($self, $clone) = @_;
1413+
1414+ @{ $clone->{_children} } = ();
1415+ $clone->add_child({}, map { $_->clone } @{ $self->{_children} });
1416+}
1417+
1418+sub children {
1419+ my $self = shift;
1420+ if ( @_ ) {
1421+ my @idx = @_;
1422+ return @{$self->{_children}}[@idx];
1423+ }
1424+ else {
1425+ if ( caller->isa( __PACKAGE__ ) || $self->isa( scalar(caller) ) ) {
1426+ return wantarray ? @{$self->{_children}} : $self->{_children};
1427+ }
1428+ else {
1429+ return grep { $_ } @{$self->{_children}};
1430+ }
1431+ }
1432+}
1433+
1434+use constant IN_ORDER => 4;
1435+
1436+# One of the things we have to do in a traversal is to remove all of the
1437+# Tree::Null elements that are appended to the tree to make this a complete
1438+# binary tree. The user isn't going to expect them, because they're an
1439+# internal nicety.
1440+
1441+sub traverse {
1442+ my $self = shift;
1443+ my $order = shift;
1444+ $order = $self->PRE_ORDER unless $order;
1445+
1446+ if ( wantarray ) {
1447+ if ( $order == $self->IN_ORDER ) {
1448+ return grep { $_ } (
1449+ $self->left->traverse( $order ),
1450+ $self,
1451+ $self->right->traverse( $order ),
1452+ );
1453+ }
1454+ else {
1455+ return grep { $_ } $self->SUPER::traverse( $order );
1456+ }
1457+ }
1458+ else {
1459+ my $closure;
1460+
1461+ if ( $order eq $self->IN_ORDER ) {
1462+ my @list = $self->traverse( $order );
1463+
1464+ $closure = sub {
1465+ return unless @list;
1466+ return shift @list;
1467+ };
1468+ }
1469+ elsif ( $order eq $self->PRE_ORDER ) {
1470+ my $next_node = $self;
1471+ my @stack = ( $self );
1472+ my @next_meth = ( 0 );
1473+
1474+ my @meths = qw( left right );
1475+ $closure = sub {
1476+ my $node = $next_node;
1477+ return unless $node;
1478+ $next_node = undef;
1479+
1480+ while ( @stack && !$next_node ) {
1481+ while ( @next_meth && $next_meth[0] == 2 ) {
1482+ shift @stack;
1483+ shift @next_meth;
1484+ }
1485+
1486+ if ( @stack ) {
1487+ my $meth = $meths[ $next_meth[0]++ ];
1488+ $next_node = $stack[0]->$meth;
1489+ next unless $next_node;
1490+ unshift @stack, $next_node;
1491+ unshift @next_meth, 0;
1492+ }
1493+ }
1494+
1495+ return $node;
1496+ };
1497+ }
1498+ elsif ( $order eq $self->POST_ORDER ) {
1499+ my @list = $self->traverse( $order );
1500+
1501+ $closure = sub {
1502+ return unless @list;
1503+ return shift @list;
1504+ };
1505+ #my @stack = ( $self );
1506+ #my @next_idx = ( 0 );
1507+ #while ( @{ $stack[0]->{_children} } ) {
1508+ # unshift @stack, $stack[0]->{_children}[0];
1509+ # unshift @next_idx, 0;
1510+ #}
1511+ #
1512+ #$closure = sub {
1513+ # my $node = $stack[0] || return;
1514+ #
1515+ # shift @stack; shift @next_idx;
1516+ # $next_idx[0]++;
1517+ #
1518+ # while ( @stack && exists $stack[0]->{_children}[ $next_idx[0] ] ) {
1519+ # unshift @stack, $stack[0]->{_children}[ $next_idx[0] ];
1520+ # unshift @next_idx, 0;
1521+ # }
1522+ #
1523+ # return $node;
1524+ #};
1525+ }
1526+ elsif ( $order eq $self->LEVEL_ORDER ) {
1527+ my @nodes = ($self);
1528+ $closure = sub {
1529+ my $node = shift @nodes;
1530+ return unless $node;
1531+ push @nodes, grep { $_ } @{$node->{_children}};
1532+ return $node;
1533+ };
1534+ }
1535+ else {
1536+ return $self->error( "traverse(): '$order' is an illegal traversal order" );
1537+ }
1538+
1539+ return $closure;
1540+ }
1541+}
1542+
1543+1;
1544+__END__
1545+
1546+=head1 NAME
1547+
1548+Tree::Binary2 - An implementation of a binary tree
1549+
1550+=head1 SYNOPSIS
1551+
1552+ my $tree = Tree::Binary2->new( 'root' );
1553+
1554+ my $left = Tree::Binary2->new( 'left' );
1555+ $tree->left( $left );
1556+
1557+ my $right = Tree::Binary2->new( 'left' );
1558+ $tree->right( $right );
1559+
1560+ my $right_child = $tree->right;
1561+
1562+ $tree->right( undef ); # Unset the right child.
1563+
1564+ my @nodes = $tree->traverse( $tree->POST_ORDER );
1565+
1566+ my $traversal = $tree->traverse( $tree->IN_ORDER );
1567+ while ( my $node = $traversal->() ) {
1568+ # Do something with $node here
1569+ }
1570+
1571+=head1 DESCRIPTION
1572+
1573+This is an implementation of a binary tree. This class inherits from L<Tree>,
1574+which is an N-ary tree implemenation. Because of this, this class actually
1575+provides an implementation of a complete binary tree vs. a sparse binary tree.
1576+The empty nodes are instances of Tree::Null, which is described in L<Tree>.
1577+This should have no effect on your usage of this class.
1578+
1579+=head1 METHODS
1580+
1581+In addition to the methods provided by L<Tree>, the following items are
1582+provided or overriden.
1583+
1584+=over 4
1585+
1586+=item * C<left([$child])> / C<right([$child])>
1587+
1588+These access the left and right children, respectively. They are mutators,
1589+which means that their behavior changes depending on if you pass in a value.
1590+
1591+If you do not pass in any parameters, then it will act as a getter for the
1592+specific child, return the child (if set) or undef (if not).
1593+
1594+If you pass in a child, it will act as a setter for the specific child,
1595+setting the child to the passed-in value and returning the $tree. (Thus, this
1596+method chains.)
1597+
1598+If you wish to unset the child, do C<$treeE<gt>left( undef );>
1599+
1600+=item * C<children()>
1601+
1602+This will return the children of the tree.
1603+
1604+B<NOTE:> There will be two children, always. Tree::Binary2 implements a
1605+complete binary tree, filling in missing children with Tree::Null objects.
1606+(Please see L<Tree::Fast> for more information on Tree::Null.)
1607+
1608+=item * B<traverse( [$order] )>
1609+
1610+When called in list context (C<my @traversal = $tree-E<gt>traverse()>), this will
1611+return a list of the nodes in the given traversal order. When called in scalar
1612+context (C<my $traversal = $tree-E<gt>traverse()>), this will return a closure
1613+that will, over successive calls, iterate over the nodes in the given
1614+traversal order. When finished it will return false.
1615+
1616+The default traversal order is pre-order.
1617+
1618+In addition to the traversal orders provided by L<Tree>, Tree::Binary2 provides
1619+in-order traversals.
1620+
1621+=over 4
1622+
1623+=item * In-order
1624+
1625+This will return the result of an in-order traversal on the left node (if
1626+any), then the node, then the result of an in-order traversal on the right
1627+node (if any).
1628+
1629+=back
1630+
1631+=back
1632+
1633+B<NOTE:> You have access to all the methods provided by L<Tree>, but it is not
1634+recommended that you use many of them, unless you know what you're doing. This
1635+list includes C<add_child()> and C<remove_child()>.
1636+
1637+=head1 TODO
1638+
1639+=over 4
1640+
1641+=item * Make in-order closure traversal work iteratively
1642+
1643+=item * Make post-order closure traversal work iteratively
1644+
1645+=back
1646+
1647+=head1 CODE COVERAGE
1648+
1649+Please see the relevant sections of L<Tree>.
1650+
1651+=head1 SUPPORT
1652+
1653+Please see the relevant sections of L<Tree>.
1654+
1655+=head1 AUTHORS
1656+
1657+Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>
1658+
1659+Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
1660+
1661+Thanks to Infinity Interactive for generously donating our time.
1662+
1663+=head1 COPYRIGHT AND LICENSE
1664+
1665+Copyright 2004, 2005 by Infinity Interactive, Inc.
1666+
1667+L<http://www.iinteractive.com>
1668+
1669+This library is free software; you can redistribute it and/or modify it under
1670+the same terms as Perl itself.
1671+
1672+=cut
1673
1674=== modified file 'lib/Tree/Fast.pm' (properties changed: +x to -x)
1675--- lib/Tree/Fast.pm 2008-01-17 12:56:58 +0000
1676+++ lib/Tree/Fast.pm 2014-12-12 23:08:52 +0000
1677@@ -1,543 +1,547 @@
1678-package Tree::Fast;
1679-
1680-use 5.006;
1681-
1682-use strict;
1683-use warnings FATAL => 'all';
1684-
1685-our $VERSION = '1.01';
1686-
1687-use Scalar::Util qw( blessed weaken );
1688-
1689-sub new {
1690- my $class = shift;
1691-
1692- return $class->clone( @_ )
1693- if blessed $class;
1694-
1695- my $self = bless {}, $class;
1696-
1697- $self->_init( @_ );
1698-
1699- return $self;
1700-}
1701-
1702-sub _init {
1703- my $self = shift;
1704- my ($value) = @_;
1705-
1706- $self->{_parent} = $self->_null,
1707- $self->{_children} = [];
1708- $self->{_value} = $value,
1709-
1710- $self->{_meta} = {};
1711-
1712- return $self;
1713-}
1714-
1715-sub _clone_self {
1716- my $self = shift;
1717-
1718- my $value = @_ ? shift : $self->value;
1719- my $clone = blessed($self)->new( $value );
1720- return blessed($self)->new( $value );
1721-}
1722-
1723-sub _clone_children {
1724- my ($self, $clone) = @_;
1725-
1726- if ( my @children = @{$self->{_children}} ) {
1727- $clone->add_child({}, map { $_->clone } @children );
1728- }
1729-}
1730-
1731-sub clone {
1732- my $self = shift;
1733-
1734- return $self->new(@_) unless blessed $self;
1735-
1736- my $clone = $self->_clone_self(@_);
1737- $self->_clone_children($clone);
1738-
1739- return $clone;
1740-}
1741-
1742-sub add_child {
1743- my $self = shift;
1744- my ( $options, @nodes ) = @_;
1745-
1746- for my $node ( @nodes ) {
1747- $node->_set_parent( $self );
1748- }
1749-
1750- if ( defined $options->{at} ) {
1751- if ( $options->{at} ) {
1752- splice @{$self->{_children}}, $options->{at}, 0, @nodes;
1753- }
1754- else {
1755- unshift @{$self->{_children}}, @nodes;
1756- }
1757- }
1758- else {
1759- push @{$self->{_children}}, @nodes;
1760- }
1761-
1762- return $self;
1763-}
1764-
1765-sub remove_child {
1766- my $self = shift;
1767- my ($options, @indices) = @_;
1768-
1769- my @return;
1770- for my $idx (sort { $b <=> $a } @indices) {
1771- my $node = splice @{$self->{_children}}, $idx, 1;
1772- $node->_set_parent( $node->_null );
1773-
1774- push @return, $node;
1775- }
1776-
1777- return @return;
1778-}
1779-
1780-sub parent {
1781- my $self = shift;
1782- return $self->{_parent};
1783-}
1784-
1785-sub _set_parent {
1786- my $self = shift;
1787-
1788- $self->{_parent} = shift;
1789- weaken( $self->{_parent} );
1790-
1791- return $self;
1792-}
1793-
1794-sub children {
1795- my $self = shift;
1796- if ( @_ ) {
1797- my @idx = @_;
1798- return @{$self->{_children}}[@idx];
1799- }
1800- else {
1801- if ( caller->isa( __PACKAGE__ ) || $self->isa( scalar(caller) ) ) {
1802- return wantarray ? @{$self->{_children}} : $self->{_children};
1803- }
1804- else {
1805- return @{$self->{_children}};
1806- }
1807- }
1808-}
1809-
1810-sub value {
1811- my $self = shift;
1812- return $self->{_value};
1813-}
1814-
1815-sub set_value {
1816- my $self = shift;
1817-
1818- $self->{_value} = $_[0];
1819-
1820- return $self;
1821-}
1822-
1823-sub meta {
1824- my $self = shift;
1825- return $self->{_meta};
1826-}
1827-
1828-sub mirror {
1829- my $self = shift;
1830-
1831- @{$self->{_children}} = reverse @{$self->{_children}};
1832- $_->mirror for @{$self->{_children}};
1833-
1834- return $self;
1835-}
1836-
1837-use constant PRE_ORDER => 1;
1838-use constant POST_ORDER => 2;
1839-use constant LEVEL_ORDER => 3;
1840-
1841-sub traverse {
1842- my $self = shift;
1843- my $order = shift;
1844- $order = $self->PRE_ORDER unless $order;
1845-
1846- if ( wantarray ) {
1847- my @list;
1848-
1849- if ( $order eq $self->PRE_ORDER ) {
1850- @list = ($self);
1851- push @list, map { $_->traverse( $order ) } @{$self->{_children}};
1852- }
1853- elsif ( $order eq $self->POST_ORDER ) {
1854- @list = map { $_->traverse( $order ) } @{$self->{_children}};
1855- push @list, $self;
1856- }
1857- elsif ( $order eq $self->LEVEL_ORDER ) {
1858- my @queue = ($self);
1859- while ( my $node = shift @queue ) {
1860- push @list, $node;
1861- push @queue, @{$node->{_children}};
1862- }
1863- }
1864- else {
1865- return $self->error( "traverse(): '$order' is an illegal traversal order" );
1866- }
1867-
1868- return @list;
1869- }
1870- else {
1871- my $closure;
1872-
1873- if ( $order eq $self->PRE_ORDER ) {
1874- my $next_node = $self;
1875- my @stack = ( $self );
1876- my @next_idx = ( 0 );
1877-
1878- $closure = sub {
1879- my $node = $next_node;
1880- return unless $node;
1881- $next_node = undef;
1882-
1883- while ( @stack && !$next_node ) {
1884- while ( @stack && !exists $stack[0]->{_children}[ $next_idx[0] ] ) {
1885- shift @stack;
1886- shift @next_idx;
1887- }
1888-
1889- if ( @stack ) {
1890- $next_node = $stack[0]->{_children}[ $next_idx[0]++ ];
1891- unshift @stack, $next_node;
1892- unshift @next_idx, 0;
1893- }
1894- }
1895-
1896- return $node;
1897- };
1898- }
1899- elsif ( $order eq $self->POST_ORDER ) {
1900- my @stack = ( $self );
1901- my @next_idx = ( 0 );
1902- while ( @{ $stack[0]->{_children} } ) {
1903- unshift @stack, $stack[0]->{_children}[0];
1904- unshift @next_idx, 0;
1905- }
1906-
1907- $closure = sub {
1908- my $node = $stack[0];
1909- return unless $node;
1910-
1911- shift @stack; shift @next_idx;
1912- $next_idx[0]++;
1913-
1914- while ( @stack && exists $stack[0]->{_children}[ $next_idx[0] ] ) {
1915- unshift @stack, $stack[0]->{_children}[ $next_idx[0] ];
1916- unshift @next_idx, 0;
1917- }
1918-
1919- return $node;
1920- };
1921- }
1922- elsif ( $order eq $self->LEVEL_ORDER ) {
1923- my @nodes = ($self);
1924- $closure = sub {
1925- my $node = shift @nodes;
1926- return unless $node;
1927- push @nodes, @{$node->{_children}};
1928- return $node;
1929- };
1930- }
1931- else {
1932- return $self->error( "traverse(): '$order' is an illegal traversal order" );
1933- }
1934-
1935- return $closure;
1936- }
1937-}
1938-
1939-sub _null {
1940- return Tree::Null->new;
1941-}
1942-
1943-package Tree::Null;
1944-
1945-#XXX Add this in once it's been thought out
1946-#our @ISA = qw( Tree );
1947-
1948-# You want to be able to interrogate the null object as to
1949-# its class, so we don't override isa() as we do can()
1950-
1951-use overload
1952- '""' => sub { return "" },
1953- '0+' => sub { return 0 },
1954- 'bool' => sub { return },
1955- fallback => 1,
1956-;
1957-
1958-{
1959- my $singleton = bless \my($x), __PACKAGE__;
1960- sub new { return $singleton }
1961- sub AUTOLOAD { return $singleton }
1962- sub can { return sub { return $singleton } }
1963-}
1964-
1965-# The null object can do anything
1966-sub isa {
1967- my ($proto, $class) = @_;
1968-
1969- if ( $class =~ /^Tree(?:::.*)?$/ ) {
1970- return 1;
1971- }
1972-
1973- return $proto->SUPER::isa( $class );
1974-}
1975-
1976-1;
1977-__END__
1978-
1979-=head1 NAME
1980-
1981-Tree::Fast - the fastest possible implementation of a tree in pure Perl
1982-
1983-=head1 SYNOPSIS
1984-
1985- my $tree = Tree->new( 'root' );
1986- my $child = Tree->new( 'child' );
1987- $tree->add_child( {}, $child );
1988-
1989- $tree->add_child( { at => 0 }, Tree->new( 'first child' ) );
1990- $tree->add_child( { at => -1 }, Tree->new( 'last child' ) );
1991-
1992- my @children = $tree->children;
1993- my @some_children = $tree->children( 0, 2 );
1994-
1995- $tree->remove_child( 0 );
1996-
1997- my @nodes = $tree->traverse( $tree->POST_ORDER );
1998-
1999- my $traversal = $tree->traverse( $tree->POST_ORDER );
2000- while ( my $node = $traversal->() ) {
2001- # Do something with $node here
2002- }
2003-
2004- my $clone = $tree->clone;
2005- my $mirror = $tree->clone->mirror;
2006-
2007-=head1 DESCRIPTION
2008-
2009-This is meant to be the core implementation for L<Tree>, stripped down as much
2010-as possible. There is no error-checking, bounds-checking, event-handling,
2011-convenience methods, or anything else of the sort. If you want something fuller-
2012-featured, please look at L<Tree>, which is a wrapper around Tree::Fast.
2013-
2014-=head1 METHODS
2015-
2016-=head2 Constructor
2017-
2018-=over 4
2019-
2020-=item B<new([$value])>
2021-
2022-This will return a Tree object. It will accept one parameter which, if passed,
2023-will become the value (accessible by L<value()>). All other parameters will be
2024-ignored.
2025-
2026-If you call C<$tree-E<gt>new([$value])>, it will instead call C<clone()>, then set
2027-the value of the clone to $value.
2028-
2029-=item B<clone()>
2030-
2031-This will return a clone of C<$tree>. The clone will be a root tree, but all
2032-children will be cloned.
2033-
2034-If you call C<Tree-E<gt>clone([$value])>, it will instead call C<new()>.
2035-
2036-B<NOTE:> the value is merely a shallow copy. This means that all references
2037-will be kept.
2038-
2039-=back
2040-
2041-=head2 Behaviors
2042-
2043-=over 4
2044-
2045-=item B<add_child($options, @nodes)>
2046-
2047-This will add all the @nodes as children of C<$tree>. $options is a required
2048-hashref that specifies options for add_child(). The optional parameters are:
2049-
2050-=over 4
2051-
2052-=item * at
2053-
2054-This specifies the index to add @nodes at. If specified, this will be passed
2055-into splice(). The only exceptions are if this is 0, it will act as an
2056-unshift(). If it is unset or undefined, it will act as a push().
2057-
2058-=back
2059-
2060-=item B<remove_child($options, @nodes)>
2061-
2062-This will remove all the @nodes from the children of C<$tree>. You can either
2063-pass in the actual child object you wish to remove, the index of the child you
2064-wish to remove, or a combination of both.
2065-
2066-$options is a required hashref that specifies parameters for remove_child().
2067-Currently, no parameters are used.
2068-
2069-=item B<mirror()>
2070-
2071-This will modify the tree such that it is a mirror of what it was before. This
2072-means that the order of all children is reversed.
2073-
2074-B<NOTE>: This is a destructive action. It I<will> modify the tree's internal
2075-structure. If you wish to get a mirror, yet keep the original tree intact, use
2076-C<my $mirror = $tree-E<gt>clone-E<gt>mirror;>
2077-
2078-=item B<traverse( [$order] )>
2079-
2080-When called in list context (C<my @traversal = $tree-E<gt>traverse()>), this will
2081-return a list of the nodes in the given traversal order. When called in scalar
2082-context (C<my $traversal = $tree-E<gt>traverse()>), this will return a closure
2083-that will, over successive calls, iterate over the nodes in the given
2084-traversal order. When finished it will return false.
2085-
2086-The default traversal order is pre-order.
2087-
2088-The various traversal orders do the following steps:
2089-
2090-=over 4
2091-
2092-=item * Pre-order (aka Prefix traversal)
2093-
2094-This will return the node, then the first sub tree in pre-order traversal,
2095-then the next sub tree, etc.
2096-
2097-Use C<$tree-E<gt>PRE_ORDER> as the C<$order>.
2098-
2099-=item * Post-order (aka Prefix traversal)
2100-
2101-This will return the each sub-tree in post-order traversal, then the node.
2102-
2103-Use C<$tree-E<gt>POST_ORDER> as the C<$order>.
2104-
2105-=item * Level-order (aka Prefix traversal)
2106-
2107-This will return the node, then the all children of the node, then all
2108-grandchildren of the node, etc.
2109-
2110-Use C<$tree-E<gt>LEVEL_ORDER> as the C<$order>.
2111-
2112-=back
2113-
2114-=back
2115-
2116-=head2 Accessors
2117-
2118-=over 4
2119-
2120-=item * B<parent()>
2121-
2122-This will return the parent of C<$tree>.
2123-
2124-=item * B<children( [ $idx, [$idx, ..] ] )>
2125-
2126-This will return the children of C<$tree>. If called in list context, it will
2127-return all the children. If called in scalar context, it will return the
2128-number of children.
2129-
2130-You may optionally pass in a list of indices to retrieve. This will return the
2131-children in the order you asked for them. This is very much like an
2132-arrayslice.
2133-
2134-=item * B<value()>
2135-
2136-This will return the value stored in the node.
2137-
2138-=item * B<set_value([$value])>
2139-
2140-This will set the value stored in the node to $value, then return $self.
2141-
2142-=item * B<meta()>
2143-
2144-This will return a hashref that can be used to store whatever metadata the client
2145-wishes to store. For example, L<Tree::Persist::DB> uses this to store database
2146-row ids.
2147-
2148-It is recommended that you store your metadata in a subhashref and not in the
2149-top-level metadata hashref, keyed by your package name. L<Tree::Persist> does
2150-this, using a unique key for each persistence layer associated with that tree.
2151-This will help prevent clobbering of metadata.
2152-
2153-=back
2154-
2155-=head1 NULL TREE
2156-
2157-If you call C<$self-E<gt>parent> on a root node, it will return a Tree::Null
2158-object. This is an implementation of the Null Object pattern optimized for
2159-usage with L<Forest>. It will evaluate as false in every case (using
2160-L<overload>) and all methods called on it will return a Tree::Null object.
2161-
2162-=head2 Notes
2163-
2164-=over 4
2165-
2166-=item *
2167-
2168-Tree::Null does B<not> inherit from anything. This is so that all the
2169-methods will go through AUTOLOAD vs. the actual method.
2170-
2171-=item *
2172-
2173-However, calling isa() on a Tree::Null object will report that it is-a
2174-any object that is either Tree or in the Tree:: hierarchy.
2175-
2176-=item *
2177-
2178-The Tree::Null object is a singleton.
2179-
2180-=item *
2181-
2182-The Tree::Null object I<is> defined, though. I couldn't find a way to
2183-make it evaluate as undefined. That may be a good thing.
2184-
2185-=back
2186-
2187-=head1 CODE COVERAGE
2188-
2189-Please see the relevant sections of L<Tree>.
2190-
2191-=head1 SUPPORT
2192-
2193-Please see the relevant sections of L<Tree>.
2194-
2195-=head1 ACKNOWLEDGEMENTS
2196-
2197-=over 4
2198-
2199-=item * Stevan Little for writing L<Tree::Simple>, upon which Tree is based.
2200-
2201-=back
2202-
2203-=head1 AUTHORS
2204-
2205-Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>
2206-
2207-Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
2208-
2209-Thanks to Infinity Interactive for generously donating our time.
2210-
2211-=head1 COPYRIGHT AND LICENSE
2212-
2213-Copyright 2004, 2005 by Infinity Interactive, Inc.
2214-
2215-L<http://www.iinteractive.com>
2216-
2217-This library is free software; you can redistribute it and/or modify it under
2218-the same terms as Perl itself.
2219-
2220-=cut
2221+package Tree::Fast;
2222+
2223+use 5.006;
2224+
2225+use strict;
2226+use warnings FATAL => 'all';
2227+
2228+our $VERSION = '1.05';
2229+
2230+use Scalar::Util qw( blessed weaken );
2231+
2232+sub new {
2233+ my $class = shift;
2234+
2235+ return $class->clone( @_ )
2236+ if blessed $class;
2237+
2238+ my $self = bless {}, $class;
2239+
2240+ $self->_init( @_ );
2241+
2242+ return $self;
2243+}
2244+
2245+sub _init {
2246+ my $self = shift;
2247+ my ($value) = @_;
2248+
2249+ $self->{_parent} = $self->_null,
2250+ $self->{_children} = [];
2251+ $self->{_value} = $value,
2252+
2253+ $self->{_meta} = {};
2254+
2255+ return $self;
2256+}
2257+
2258+sub _clone_self {
2259+ my $self = shift;
2260+
2261+ my $value = @_ ? shift : $self->value;
2262+ my $clone = blessed($self)->new( $value );
2263+ return blessed($self)->new( $value );
2264+}
2265+
2266+sub _clone_children {
2267+ my ($self, $clone) = @_;
2268+
2269+ if ( my @children = @{$self->{_children}} ) {
2270+ $clone->add_child({}, map { $_->clone } @children );
2271+ }
2272+}
2273+
2274+sub clone {
2275+ my $self = shift;
2276+
2277+ return $self->new(@_) unless blessed $self;
2278+
2279+ my $clone = $self->_clone_self(@_);
2280+ $self->_clone_children($clone);
2281+
2282+ return $clone;
2283+}
2284+
2285+sub add_child {
2286+ my $self = shift;
2287+ my ( $options, @nodes ) = @_;
2288+
2289+ for my $node ( @nodes ) {
2290+ $node->_set_parent( $self );
2291+ }
2292+
2293+ if ( defined $options->{at} ) {
2294+ if ( $options->{at} ) {
2295+ splice @{$self->{_children}}, $options->{at}, 0, @nodes;
2296+ }
2297+ else {
2298+ unshift @{$self->{_children}}, @nodes;
2299+ }
2300+ }
2301+ else {
2302+ push @{$self->{_children}}, @nodes;
2303+ }
2304+
2305+ return $self;
2306+}
2307+
2308+sub remove_child {
2309+ my $self = shift;
2310+ my ($options, @indices) = @_;
2311+
2312+ my @return;
2313+ for my $idx (sort { $b <=> $a } @indices) {
2314+ my $node = splice @{$self->{_children}}, $idx, 1;
2315+ $node->_set_parent( $node->_null );
2316+
2317+ push @return, $node;
2318+ }
2319+
2320+ return @return;
2321+}
2322+
2323+sub parent {
2324+ my $self = shift;
2325+ return $self->{_parent};
2326+}
2327+
2328+sub _set_parent {
2329+ my $self = shift;
2330+
2331+ $self->{_parent} = shift;
2332+ weaken( $self->{_parent} );
2333+
2334+ return $self;
2335+}
2336+
2337+sub children {
2338+ my $self = shift;
2339+ if ( @_ ) {
2340+ my @idx = @_;
2341+ return @{$self->{_children}}[@idx];
2342+ }
2343+ else {
2344+ if ( caller->isa( __PACKAGE__ ) || $self->isa( scalar(caller) ) ) {
2345+ return wantarray ? @{$self->{_children}} : $self->{_children};
2346+ }
2347+ else {
2348+ return @{$self->{_children}};
2349+ }
2350+ }
2351+}
2352+
2353+sub value {
2354+ my $self = shift;
2355+ my $value = shift;
2356+ $self->{_value} = $value if (defined $value);
2357+
2358+ return $self->{_value};
2359+}
2360+
2361+sub set_value {
2362+ my $self = shift;
2363+
2364+ $self->{_value} = $_[0];
2365+
2366+ return $self;
2367+}
2368+
2369+sub meta {
2370+ my $self = shift;
2371+ my $meta = shift;
2372+ $self->{_meta} = {%{$self->{_meta} }, %$meta} if ($meta && !blessed($meta) && ref($meta) eq 'HASH');
2373+
2374+ return $self->{_meta};
2375+}
2376+
2377+sub mirror {
2378+ my $self = shift;
2379+
2380+ @{$self->{_children}} = reverse @{$self->{_children}};
2381+ $_->mirror for @{$self->{_children}};
2382+
2383+ return $self;
2384+}
2385+
2386+use constant PRE_ORDER => 1;
2387+use constant POST_ORDER => 2;
2388+use constant LEVEL_ORDER => 3;
2389+
2390+sub traverse {
2391+ my $self = shift;
2392+ my $order = shift;
2393+ $order = $self->PRE_ORDER unless $order;
2394+
2395+ if ( wantarray ) {
2396+ my @list;
2397+
2398+ if ( $order eq $self->PRE_ORDER ) {
2399+ @list = ($self);
2400+ push @list, map { $_->traverse( $order ) } @{$self->{_children}};
2401+ }
2402+ elsif ( $order eq $self->POST_ORDER ) {
2403+ @list = map { $_->traverse( $order ) } @{$self->{_children}};
2404+ push @list, $self;
2405+ }
2406+ elsif ( $order eq $self->LEVEL_ORDER ) {
2407+ my @queue = ($self);
2408+ while ( my $node = shift @queue ) {
2409+ push @list, $node;
2410+ push @queue, @{$node->{_children}};
2411+ }
2412+ }
2413+ else {
2414+ return $self->error( "traverse(): '$order' is an illegal traversal order" );
2415+ }
2416+
2417+ return @list;
2418+ }
2419+ else {
2420+ my $closure;
2421+
2422+ if ( $order eq $self->PRE_ORDER ) {
2423+ my $next_node = $self;
2424+ my @stack = ( $self );
2425+ my @next_idx = ( 0 );
2426+
2427+ $closure = sub {
2428+ my $node = $next_node;
2429+ return unless $node;
2430+ $next_node = undef;
2431+
2432+ while ( @stack && !$next_node ) {
2433+ while ( @stack && !exists $stack[0]->{_children}[ $next_idx[0] ] ) {
2434+ shift @stack;
2435+ shift @next_idx;
2436+ }
2437+
2438+ if ( @stack ) {
2439+ $next_node = $stack[0]->{_children}[ $next_idx[0]++ ];
2440+ unshift @stack, $next_node;
2441+ unshift @next_idx, 0;
2442+ }
2443+ }
2444+
2445+ return $node;
2446+ };
2447+ }
2448+ elsif ( $order eq $self->POST_ORDER ) {
2449+ my @stack = ( $self );
2450+ my @next_idx = ( 0 );
2451+ while ( @{ $stack[0]->{_children} } ) {
2452+ unshift @stack, $stack[0]->{_children}[0];
2453+ unshift @next_idx, 0;
2454+ }
2455+
2456+ $closure = sub {
2457+ my $node = $stack[0];
2458+ return unless $node;
2459+
2460+ shift @stack; shift @next_idx;
2461+ $next_idx[0]++;
2462+
2463+ while ( @stack && exists $stack[0]->{_children}[ $next_idx[0] ] ) {
2464+ unshift @stack, $stack[0]->{_children}[ $next_idx[0] ];
2465+ unshift @next_idx, 0;
2466+ }
2467+
2468+ return $node;
2469+ };
2470+ }
2471+ elsif ( $order eq $self->LEVEL_ORDER ) {
2472+ my @nodes = ($self);
2473+ $closure = sub {
2474+ my $node = shift @nodes;
2475+ return unless $node;
2476+ push @nodes, @{$node->{_children}};
2477+ return $node;
2478+ };
2479+ }
2480+ else {
2481+ return $self->error( "traverse(): '$order' is an illegal traversal order" );
2482+ }
2483+
2484+ return $closure;
2485+ }
2486+}
2487+
2488+sub _null {
2489+ return Tree::Null->new;
2490+}
2491+
2492+package Tree::Null;
2493+
2494+#XXX Add this in once it's been thought out
2495+#our @ISA = qw( Tree );
2496+
2497+# You want to be able to interrogate the null object as to
2498+# its class, so we don't override isa() as we do can()
2499+
2500+use overload
2501+ '""' => sub { return "" },
2502+ '0+' => sub { return 0 },
2503+ 'bool' => sub { return },
2504+ fallback => 1,
2505+;
2506+
2507+{
2508+ my $singleton = bless \my($x), __PACKAGE__;
2509+ sub new { return $singleton }
2510+ sub AUTOLOAD { return $singleton }
2511+ sub can { return sub { return $singleton } }
2512+}
2513+
2514+# The null object can do anything
2515+sub isa {
2516+ my ($proto, $class) = @_;
2517+
2518+ if ( $class =~ /^Tree(?:::.*)?$/ ) {
2519+ return 1;
2520+ }
2521+
2522+ return $proto->SUPER::isa( $class );
2523+}
2524+
2525+1;
2526+__END__
2527+
2528+=head1 NAME
2529+
2530+Tree::Fast - the fastest possible implementation of a tree in pure Perl
2531+
2532+=head1 SYNOPSIS
2533+
2534+ my $tree = Tree->new( 'root' );
2535+ my $child = Tree->new( 'child' );
2536+ $tree->add_child( {}, $child );
2537+
2538+ $tree->add_child( { at => 0 }, Tree->new( 'first child' ) );
2539+ $tree->add_child( { at => -1 }, Tree->new( 'last child' ) );
2540+
2541+ my @children = $tree->children;
2542+ my @some_children = $tree->children( 0, 2 );
2543+
2544+ $tree->remove_child( 0 );
2545+
2546+ my @nodes = $tree->traverse( $tree->POST_ORDER );
2547+
2548+ my $traversal = $tree->traverse( $tree->POST_ORDER );
2549+ while ( my $node = $traversal->() ) {
2550+ # Do something with $node here
2551+ }
2552+
2553+ my $clone = $tree->clone;
2554+ my $mirror = $tree->clone->mirror;
2555+
2556+=head1 DESCRIPTION
2557+
2558+This is meant to be the core implementation for L<Tree>, stripped down as much
2559+as possible. There is no error-checking, bounds-checking, event-handling,
2560+convenience methods, or anything else of the sort. If you want something fuller-featured,
2561+please look at L<Tree>, which is a wrapper around Tree::Fast.
2562+
2563+=head1 METHODS
2564+
2565+=head2 Constructors
2566+
2567+=head2 new([$value])
2568+
2569+Here, [] indicate an optional parameter.
2570+
2571+This will return a C<Tree> object. It will accept one parameter which, if passed,
2572+will become the I<value> (accessible by C<value()>). All other parameters will be
2573+ignored.
2574+
2575+If you call C<< $tree->new([$value]) >>, it will instead call C<clone()>, then set
2576+the I<value> of the clone to $value.
2577+
2578+=head2 clone()
2579+
2580+This will return a clone of C<$tree>. The clone will be a root tree, but all
2581+children will be cloned.
2582+
2583+If you call C<< Tree->clone([$value]) >>, it will instead call C<new()>.
2584+
2585+B<NOTE:> the value is merely a shallow copy. This means that all references
2586+will be kept.
2587+
2588+=head2 Behaviors
2589+
2590+=head2 add_child($options, @nodes)
2591+
2592+This will add all the C<@nodes> as children of C<$tree>. C<$options> is a required
2593+hashref that specifies options for C<add_child()>. The optional parameters are:
2594+
2595+=over 4
2596+
2597+=item * at
2598+
2599+This specifies the index to add C<@nodes> at. If specified, this will be passed
2600+into splice(). The only exceptions are if this is 0, it will act as an
2601+unshift(). If it is unset or undefined, it will act as a push().
2602+
2603+=back
2604+
2605+=head2 remove_child($options, @nodes)
2606+
2607+This will remove all the C<@nodes> from the children of C<$tree>. You can either
2608+pass in the actual child object you wish to remove, the index of the child you
2609+wish to remove, or a combination of both.
2610+
2611+$options is a required hashref that specifies parameters for remove_child().
2612+Currently, no parameters are used.
2613+
2614+=head2 mirror()
2615+
2616+This will modify the tree such that it is a mirror of what it was before. This
2617+means that the order of all children is reversed.
2618+
2619+B<NOTE>: This is a destructive action. It I<will> modify the tree's internal
2620+structure. If you wish to get a mirror, yet keep the original tree intact, use
2621+C<< my $mirror = $tree->clone->mirror >>.
2622+
2623+=head2 traverse( [$order] )
2624+
2625+Here, [] indicate an optional parameter.
2626+
2627+When called in list context (C<< my @traversal = $tree->traverse() >>), this will
2628+return a list of the nodes in the given traversal order. When called in scalar
2629+context (C<< my $traversal = $tree->traverse() >>), this will return a closure
2630+that will, over successive calls, iterate over the nodes in the given
2631+traversal order. When finished it will return false.
2632+
2633+The default traversal order is pre-order.
2634+
2635+The various traversal orders do the following steps:
2636+
2637+=over 4
2638+
2639+=item * Pre-order
2640+
2641+This will return the node, then the first sub tree in pre-order traversal,
2642+then the next sub tree, etc.
2643+
2644+Use C<< $tree->PRE_ORDER >> as the C<$order>.
2645+
2646+=item * Post-order
2647+
2648+This will return the each sub-tree in post-order traversal, then the node.
2649+
2650+Use C<< $tree->POST_ORDER >> as the C<$order>.
2651+
2652+=item * Level-order
2653+
2654+This will return the node, then the all children of the node, then all
2655+grandchildren of the node, etc.
2656+
2657+Use C<< $tree->LEVEL_ORDER >> as the C<$order>.
2658+
2659+=back
2660+
2661+=head2 Accessors
2662+
2663+=head2 parent()
2664+
2665+This will return the parent of C<$tree>.
2666+
2667+=head2 children( [ $idx, [$idx, ..] ] )
2668+
2669+Here, [] indicate optional parameters.
2670+
2671+This will return the children of C<$tree>. If called in list context, it will
2672+return all the children. If called in scalar context, it will return the
2673+number of children.
2674+
2675+You may optionally pass in a list of indices to retrieve. This will return the
2676+children in the order you asked for them. This is very much like an
2677+arrayslice.
2678+
2679+=head2 value()
2680+
2681+This will return the value stored in the node.
2682+
2683+=head2 set_value([$value])
2684+
2685+Here, [] indicate an optional parameter.
2686+
2687+This will set the I<value> stored in the node to $value, then return $self.
2688+
2689+If C<$value> is not provided, undef is used.
2690+
2691+=head2 meta()
2692+
2693+This will return a hashref that can be used to store whatever metadata the client
2694+wishes to store. For example, L<Tree::Persist::DB> uses this to store database
2695+row ids.
2696+
2697+It is recommended that you store your metadata in a subhashref and not in the
2698+top-level metadata hashref, keyed by your package name. L<Tree::Persist> does
2699+this, using a unique key for each persistence layer associated with that tree.
2700+This will help prevent clobbering of metadata.
2701+
2702+=head1 NULL TREE
2703+
2704+If you call C<< $self->parent >> on a root node, it will return a Tree::Null
2705+object. This is an implementation of the Null Object pattern optimized for
2706+usage with L<Tree>. It will evaluate as false in every case (using
2707+I<overload>) and all methods called on it will return a Tree::Null object.
2708+
2709+=head2 Notes
2710+
2711+=over 4
2712+
2713+=item *
2714+
2715+Tree::Null does B<not> inherit from anything. This is so that all the
2716+methods will go through AUTOLOAD vs. the actual method.
2717+
2718+=item *
2719+
2720+However, calling isa() on a Tree::Null object will report that it is-a
2721+any object that is either Tree or in the Tree:: hierarchy.
2722+
2723+=item *
2724+
2725+The Tree::Null object is a singleton.
2726+
2727+=item *
2728+
2729+The Tree::Null object I<is> defined, though. I couldn't find a way to
2730+make it evaluate as undefined. That may be a good thing.
2731+
2732+=back
2733+
2734+=head1 CODE COVERAGE
2735+
2736+Please see the relevant sections of L<Tree>.
2737+
2738+=head1 SUPPORT
2739+
2740+Please see the relevant sections of L<Tree>.
2741+
2742+=head1 ACKNOWLEDGEMENTS
2743+
2744+=over 4
2745+
2746+=item * Stevan Little for writing L<Tree::Simple>, upon which Tree is based.
2747+
2748+=back
2749+
2750+=head1 AUTHORS
2751+
2752+Rob Kinyon E<lt>rob.kinyon@iinteractive.comE<gt>
2753+
2754+Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
2755+
2756+Thanks to Infinity Interactive for generously donating our time.
2757+
2758+=head1 COPYRIGHT AND LICENSE
2759+
2760+Copyright 2004, 2005 by Infinity Interactive, Inc.
2761+
2762+L<http://www.iinteractive.com>
2763+
2764+This library is free software; you can redistribute it and/or modify it under
2765+the same terms as Perl itself.
2766+
2767+=cut
2768
2769=== modified file 't/Tree/001_root_node.t'
2770--- t/Tree/001_root_node.t 2008-01-17 12:56:58 +0000
2771+++ t/Tree/001_root_node.t 2014-12-12 23:08:52 +0000
2772@@ -1,11 +1,12 @@
2773+use lib 't/lib';
2774 use strict;
2775 use warnings;
2776
2777 use Test::More;
2778
2779-use t::tests qw( %runs );
2780+use Tests qw( %runs );
2781
2782-plan tests => 25 + 3 * $runs{stats}{plan};
2783+plan tests => 26 + 3 * $runs{stats}{plan};
2784
2785 my $CLASS = 'Tree';
2786 use_ok( $CLASS )
2787@@ -39,7 +40,10 @@
2788 is( $tree->root, $tree, "... and doesn't change the value" );
2789
2790 $tree->meta->{foo} = 1;
2791- is( $tree->meta->{foo}, 1, "Meta works." );
2792+ is( $tree->meta->{foo}, 1, "Meta works via in-situ update." );
2793+
2794+ $tree->meta({baa => 2});
2795+ is( ${$tree->meta}{baa}, 2, "Meta works via method call." );
2796 }
2797
2798 {
2799
2800=== modified file 't/Tree/003_child_node.t'
2801--- t/Tree/003_child_node.t 2008-01-17 12:56:58 +0000
2802+++ t/Tree/003_child_node.t 2014-12-12 23:08:52 +0000
2803@@ -1,9 +1,10 @@
2804+use lib 't/lib';
2805 use strict;
2806 use warnings;
2807
2808 use Test::More;
2809
2810-use t::tests qw( %runs );
2811+use Tests qw( %runs );
2812
2813 plan tests => 22 + 4 * $runs{stats}{plan};
2814
2815
2816=== modified file 't/Tree/004_multiple_children.t'
2817--- t/Tree/004_multiple_children.t 2008-01-17 12:56:58 +0000
2818+++ t/Tree/004_multiple_children.t 2014-12-12 23:08:52 +0000
2819@@ -1,9 +1,10 @@
2820+use lib 't/lib';
2821 use strict;
2822 use warnings;
2823
2824 use Test::More;
2825
2826-use t::tests qw( %runs );
2827+use Tests qw( %runs );
2828
2829 plan tests => 27 + 15 * $runs{stats}{plan};
2830
2831
2832=== modified file 't/Tree/005_multilevel_tree.t'
2833--- t/Tree/005_multilevel_tree.t 2008-01-17 12:56:58 +0000
2834+++ t/Tree/005_multilevel_tree.t 2014-12-12 23:08:52 +0000
2835@@ -1,9 +1,10 @@
2836+use lib 't/lib';
2837 use strict;
2838 use warnings;
2839
2840 use Test::More;
2841
2842-use t::tests qw( %runs );
2843+use Tests qw( %runs );
2844
2845 plan tests => 41 + 3 * $runs{stats}{plan};
2846
2847
2848=== modified file 't/Tree/010_errors_addchild.t'
2849--- t/Tree/010_errors_addchild.t 2008-01-17 12:56:58 +0000
2850+++ t/Tree/010_errors_addchild.t 2014-12-12 23:08:52 +0000
2851@@ -1,9 +1,10 @@
2852+use lib 't/lib';
2853 use strict;
2854 use warnings;
2855
2856 use Test::More;
2857
2858-use t::tests qw( %runs );
2859+use Tests qw( %runs );
2860
2861 plan tests => 1 + 12 * $runs{error}{plan};
2862
2863
2864=== modified file 't/Tree/011_errors_removechild.t'
2865--- t/Tree/011_errors_removechild.t 2008-01-17 12:56:58 +0000
2866+++ t/Tree/011_errors_removechild.t 2014-12-12 23:08:52 +0000
2867@@ -1,9 +1,10 @@
2868+use lib 't/lib';
2869 use strict;
2870 use warnings;
2871
2872 use Test::More;
2873
2874-use t::tests qw( %runs );
2875+use Tests qw( %runs );
2876
2877 plan tests => 1 + 6 * $runs{error}{plan};
2878
2879
2880=== modified file 't/Tree/016_events.t'
2881--- t/Tree/016_events.t 2008-01-17 12:56:58 +0000
2882+++ t/Tree/016_events.t 2014-12-12 23:08:52 +0000
2883@@ -1,9 +1,10 @@
2884+use lib 't/lib';
2885 use strict;
2886 use warnings;
2887
2888 use Test::More;
2889
2890-#use t::tests qw( %runs );
2891+#use Tests qw( %runs );
2892
2893 plan tests => 8;
2894
2895
2896=== modified file 't/Tree_Binary/000_binary_trees.t'
2897--- t/Tree_Binary/000_binary_trees.t 2008-01-17 12:56:58 +0000
2898+++ t/Tree_Binary/000_binary_trees.t 2014-12-12 23:08:52 +0000
2899@@ -1,13 +1,14 @@
2900+use lib 't/lib';
2901 use strict;
2902 use warnings;
2903
2904 use Test::More;
2905
2906-use t::tests qw( %runs );
2907+use Tests qw( %runs );
2908
2909 plan tests => 28 + 15 * $runs{stats}{plan};
2910
2911-my $CLASS = 'Tree::Binary';
2912+my $CLASS = 'Tree::Binary2';
2913 use_ok( $CLASS )
2914 or Test::More->builder->BAILOUT( "Cannot load $CLASS" );
2915
2916
2917=== modified file 't/Tree_Binary/001_mirror.t'
2918--- t/Tree_Binary/001_mirror.t 2008-01-17 12:56:58 +0000
2919+++ t/Tree_Binary/001_mirror.t 2014-12-12 23:08:52 +0000
2920@@ -5,7 +5,7 @@
2921
2922 plan tests => 16;
2923
2924-my $CLASS = 'Tree::Binary';
2925+my $CLASS = 'Tree::Binary2';
2926 use_ok( $CLASS )
2927 or Test::More->builder->BAILOUT( "Cannot load $CLASS" );
2928
2929
2930=== modified file 't/Tree_Binary/002_clone.t'
2931--- t/Tree_Binary/002_clone.t 2008-01-17 12:56:58 +0000
2932+++ t/Tree_Binary/002_clone.t 2014-12-12 23:08:52 +0000
2933@@ -7,11 +7,11 @@
2934
2935 use Test::More tests => 6;
2936
2937-use_ok( 'Tree::Binary' );
2938+use_ok( 'Tree::Binary2' );
2939
2940-my $tree = Tree::Binary->new('root');
2941-$tree->left(Tree::Binary->new('left'));
2942-$tree->right(Tree::Binary->new('right'));
2943+my $tree = Tree::Binary2->new('root');
2944+$tree->left(Tree::Binary2->new('left'));
2945+$tree->right(Tree::Binary2->new('right'));
2946
2947 my $clone = $tree->clone;
2948
2949
2950=== added directory 't/lib'
2951=== added file 't/lib/Tests.pm'
2952--- t/lib/Tests.pm 1970-01-01 00:00:00 +0000
2953+++ t/lib/Tests.pm 2014-12-12 23:08:52 +0000
2954@@ -0,0 +1,61 @@
2955+package Tests;
2956+
2957+use strict;
2958+use warnings;
2959+
2960+use Test::More;
2961+
2962+my @stats = qw( height width depth size is_root is_leaf );
2963+
2964+use base 'Exporter';
2965+
2966+our @EXPORT_OK = qw( %runs );
2967+our $VERSION = '1.05';
2968+
2969+our %runs = (
2970+ stats => {
2971+ plan => scalar @stats,
2972+ func => \&stat_check,
2973+ },
2974+ error => {
2975+ plan => 3,
2976+ func => \&error_check,
2977+ },
2978+);
2979+
2980+sub stat_check {
2981+ my $tree = shift;
2982+ my %opts = @_;
2983+
2984+ foreach my $stat (@stats) {
2985+ if ( $stat =~ /^is_(.*)/ ) {
2986+ if ( $opts{$stat} ) {
2987+ ok( $tree->$stat, "The tree is a $1" );
2988+ }
2989+ else {
2990+ ok( !$tree->$stat, "The tree is not a $1" );
2991+ }
2992+ }
2993+ else {
2994+ cmp_ok(
2995+ $tree->$stat, '==', $opts{$stat},
2996+ "The tree has a $stat of $opts{$stat}",
2997+ );
2998+ }
2999+ }
3000+}
3001+
3002+sub error_check {
3003+ my $tree = shift;
3004+ my %opts = @_;
3005+
3006+ my $func = $opts{func};
3007+ my $validator = $opts{validator};
3008+
3009+ is( $tree->$func(@{$opts{args} || []}), undef, "$func(): error testing ..." );
3010+ is( $tree->last_error, $opts{error}, "... and the error is good" );
3011+ cmp_ok( $tree->$validator, '==', $opts{value}, "... and there was no change" );
3012+}
3013+
3014+1;
3015+__END__
3016
3017=== modified file 't/pod.t'
3018--- t/pod.t 2008-01-17 12:56:58 +0000
3019+++ t/pod.t 2014-12-12 23:08:52 +0000
3020@@ -3,7 +3,7 @@
3021
3022 use Test::More;
3023
3024-eval "use Test::Pod 1.14";
3025-plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
3026+eval "use Test::Pod 1.45";
3027+plan skip_all => "Test::Pod 1.45 required for testing POD" if $@;
3028
3029 all_pod_files_ok();
3030
3031=== modified file 't/pod_coverage.t'
3032--- t/pod_coverage.t 2008-01-17 12:56:58 +0000
3033+++ t/pod_coverage.t 2014-12-12 23:08:52 +0000
3034@@ -3,8 +3,8 @@
3035
3036 use Test::More;
3037
3038-eval "use Test::Pod::Coverage 1.04";
3039-plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@;
3040+eval "use Test::Pod::Coverage 1.08";
3041+plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage" if $@;
3042
3043 all_pod_coverage_ok({
3044 also_private => [],
3045
3046=== removed file 't/tests.pm'
3047--- t/tests.pm 2008-01-17 12:56:58 +0000
3048+++ t/tests.pm 1970-01-01 00:00:00 +0000
3049@@ -1,60 +0,0 @@
3050-package t::tests;
3051-
3052-use strict;
3053-use warnings;
3054-
3055-use Test::More;
3056-
3057-my @stats = qw( height width depth size is_root is_leaf );
3058-
3059-use base 'Exporter';
3060-
3061-our @EXPORT_OK = qw( %runs );
3062-
3063-our %runs = (
3064- stats => {
3065- plan => scalar @stats,
3066- func => \&stat_check,
3067- },
3068- error => {
3069- plan => 3,
3070- func => \&error_check,
3071- },
3072-);
3073-
3074-sub stat_check {
3075- my $tree = shift;
3076- my %opts = @_;
3077-
3078- foreach my $stat (@stats) {
3079- if ( $stat =~ /^is_(.*)/ ) {
3080- if ( $opts{$stat} ) {
3081- ok( $tree->$stat, "The tree is a $1" );
3082- }
3083- else {
3084- ok( !$tree->$stat, "The tree is not a $1" );
3085- }
3086- }
3087- else {
3088- cmp_ok(
3089- $tree->$stat, '==', $opts{$stat},
3090- "The tree has a $stat of $opts{$stat}",
3091- );
3092- }
3093- }
3094-}
3095-
3096-sub error_check {
3097- my $tree = shift;
3098- my %opts = @_;
3099-
3100- my $func = $opts{func};
3101- my $validator = $opts{validator};
3102-
3103- is( $tree->$func(@{$opts{args} || []}), undef, "$func(): error testing ..." );
3104- is( $tree->last_error, $opts{error}, "... and the error is good" );
3105- cmp_ok( $tree->$validator, '==', $opts{value}, "... and there was no change" );
3106-}
3107-
3108-1;
3109-__END__

Subscribers

People subscribed via source and target branches

to all changes: