Commit | Line | Data |
3fea05b9 |
1 | |
2 | package Tree::Simple::Visitor::PathToRoot; |
3 | |
4 | use strict; |
5 | use warnings; |
6 | |
7 | our $VERSION = '0.02'; |
8 | |
9 | use Scalar::Util qw(blessed); |
10 | |
11 | use base qw(Tree::Simple::Visitor); |
12 | |
13 | sub new { |
14 | my ($_class) = @_; |
15 | my $class = ref($_class) || $_class; |
16 | my $visitor = {}; |
17 | bless($visitor, $class); |
18 | $visitor->_init(); |
19 | return $visitor; |
20 | } |
21 | |
22 | sub visit { |
23 | my ($self, $tree) = @_; |
24 | (blessed($tree) && $tree->isa("Tree::Simple")) |
25 | || die "Insufficient Arguments : You must supply a valid Tree::Simple object"; |
26 | # create an array for our path |
27 | my @path; |
28 | # we need to climb up the tree and |
29 | # collect the nodes |
30 | my $filter_function = $self->getNodeFilter(); |
31 | my $current_tree = $tree; |
32 | until ($current_tree->isRoot()) { |
33 | unshift @path => ($filter_function ? |
34 | $filter_function->($current_tree) |
35 | : |
36 | $current_tree->getNodeValue()); |
37 | $current_tree = $current_tree->getParent(); |
38 | } |
39 | # now grab the trunk if specified |
40 | unshift @path => ($filter_function ? |
41 | $filter_function->($current_tree) |
42 | : |
43 | $current_tree->getNodeValue()) if $self->includeTrunk(); |
44 | # now store our path in results |
45 | $self->setResults(@path); |
46 | } |
47 | |
48 | sub getPath { |
49 | my ($self) = @_; |
50 | return $self->getResults(); |
51 | } |
52 | |
53 | sub getPathAsString { |
54 | my ($self, $delimiter) = @_; |
55 | $delimiter ||= ", "; |
56 | return join $delimiter => $self->getResults(); |
57 | } |
58 | |
59 | 1; |
60 | |
61 | __END__ |
62 | |
63 | =head1 NAME |
64 | |
65 | Tree::Simple::Visitor::PathToRoot - A Visitor for finding the path back a Tree::Simple object's root |
66 | |
67 | =head1 SYNOPSIS |
68 | |
69 | use Tree::Simple::Visitor::PathToRoot; |
70 | |
71 | # create an instance of our visitor |
72 | my $visitor = Tree::Simple::Visitor::PathToRoot->new(); |
73 | |
74 | # pass the visitor to a Tree::Simple object |
75 | $tree->accept($visitor); |
76 | |
77 | # now get the accumulated path as a string |
78 | # with the '/' character as the delimiter |
79 | print $visitor->getPathAsString("/"); |
80 | |
81 | # include the tree's trunk in your |
82 | # output as well |
83 | $visitor->includeTrunk(); |
84 | |
85 | # for more complex node objects, you can specify |
86 | # a node filter which will be used to extract the |
87 | # information desired from each node |
88 | $visitor->setNodeFilter(sub { |
89 | my ($t) = @_; |
90 | return $t->getNodeValue()->description(); |
91 | }); |
92 | |
93 | # you can also get the path back as an array |
94 | my @path = $visitor->getPath(); |
95 | |
96 | =head1 DESCRIPTION |
97 | |
98 | Given a Tree::Simple object, this Visitor will find the path back to the tree's root node. |
99 | |
100 | =head1 METHODS |
101 | |
102 | =over 4 |
103 | |
104 | =item B<new> |
105 | |
106 | There are no arguments to the constructor the object will be in its default state. You can use the C<includeTrunk> and C<setNodeFilter> methods to customize its behavior. |
107 | |
108 | =item B<includeTrunk ($boolean)> |
109 | |
110 | Based upon the value of C<$boolean>, this will tell the visitor to collect the trunk of the tree as well. |
111 | |
112 | =item B<setNodeFilter ($filter_function)> |
113 | |
114 | This method accepts a CODE reference as its C<$filter_function> argument and throws an exception if it is not a code reference. This code reference is used to filter the tree nodes as they are collected. This can be used to customize output, or to gather specific information from a more complex tree node. The filter function should accept a single argument, which is the current Tree::Simple object. |
115 | |
116 | =item B<visit ($tree)> |
117 | |
118 | This is the method that is used by Tree::Simple's C<accept> method. It can also be used on its own, it requires the C<$tree> argument to be a Tree::Simple object (or derived from a Tree::Simple object), and will throw and exception otherwise. |
119 | |
120 | =item B<getPath> |
121 | |
122 | This will return the collected path as an array, or in scalar context, as an array reference. |
123 | |
124 | =item B<getPathAsString ($delimiter)> |
125 | |
126 | This will return the collected path as a string with the path elements joined by a C<$delimiter>. If no C<$delimiter> is specified, the default (', ') will be used. |
127 | |
128 | =back |
129 | |
130 | =head1 BUGS |
131 | |
132 | None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it. |
133 | |
134 | =head1 CODE COVERAGE |
135 | |
136 | See the B<CODE COVERAGE> section in L<Tree::Simple::VisitorFactory> for more inforamtion. |
137 | |
138 | =head1 SEE ALSO |
139 | |
140 | These Visitor classes are all subclasses of B<Tree::Simple::Visitor>, which can be found in the B<Tree::Simple> module, you should refer to that module for more information. |
141 | |
142 | =head1 AUTHOR |
143 | |
144 | stevan little, E<lt>stevan@iinteractive.comE<gt> |
145 | |
146 | =head1 COPYRIGHT AND LICENSE |
147 | |
148 | Copyright 2004, 2005 by Infinity Interactive, Inc. |
149 | |
150 | L<http://www.iinteractive.com> |
151 | |
152 | This library is free software; you can redistribute it and/or modify |
153 | it under the same terms as Perl itself. |
154 | |
155 | =cut |
156 | |