1 2package Tree::Simple::Visitor::GetAllDescendents; 3 4use strict; 5use warnings; 6 7our $VERSION = '0.02'; 8 9use Scalar::Util qw(blessed); 10 11use base qw(Tree::Simple::Visitor); 12 13sub 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 22sub _init { 23 my ($self) = @_; 24 $self->{traversal_method} = undef; 25 $self->SUPER::_init(); 26} 27 28sub setTraversalMethod { 29 my ($self, $visitor) = @_; 30 (blessed($visitor) && $visitor->isa("Tree::Simple::Visitor")) 31 || die "Insufficient Arguments : You must supply a valid Tree::Simple::Visitor object"; 32 $self->{traversal_method} = $visitor; 33} 34 35sub visit { 36 my ($self, $tree) = @_; 37 (blessed($tree) && $tree->isa("Tree::Simple")) 38 || die "Insufficient Arguments : You must supply a valid Tree::Simple object"; 39 # create an closure for the 40 # collection function 41 my @descendents; 42 my $filter_function = $self->getNodeFilter(); 43 # build a collection function 44 my $collection_function = sub { 45 my ($t) = @_; 46 push @descendents => ($filter_function ? 47 $filter_function->($t) 48 : 49 $t->getNodeValue()); 50 }; 51 # and collect our descendents with the 52 # traversal method specified 53 unless (defined($self->{traversal_method})) { 54 $tree->traverse($collection_function); 55 } 56 else { 57 $self->{traversal_method}->setNodeFilter($collection_function); 58 $self->{traversal_method}->visit($tree); 59 } 60 # now store our collected descendents 61 $self->setResults(@descendents); 62} 63 64sub getAllDescendents { 65 my ($self) = @_; 66 return $self->getResults(); 67} 68 691; 70 71__END__ 72 73=head1 NAME 74 75Tree::Simple::Visitor::GetAllDescendents - A Visitor for fetching all the descendents of a Tree::Simple object 76 77=head1 SYNOPSIS 78 79 use Tree::Simple::Visitor::GetAllDescendents; 80 81 # create an instance of our visitor 82 my $visitor = Tree::Simple::Visitor::GetAllDescendents->new(); 83 84 # pass the visitor to a Tree::Simple object 85 $tree->accept($visitor); 86 87 # you can also get the descendents 88 # back as an array of node values 89 my @descendents = $visitor->getDescendents(); 90 91 # for more complex node objects, you can specify 92 # a node filter which will be used to extract the 93 # information desired from each node 94 $visitor->setNodeFilter(sub { 95 my ($t) = @_; 96 return $t->getNodeValue()->description(); 97 }); 98 99=head1 DESCRIPTION 100 101Given a Tree::Simple instance this Visitor will return all the descendents recursively on down the hierarchy. 102 103=head1 METHODS 104 105=over 4 106 107=item B<new> 108 109There are no arguments to the constructor the object will be in its default state. You can use the C<setNodeFilter> method to customize its behavior. 110 111=item B<setTraversalMethod ($visitor)> 112 113By default we will use Tree::Simple's built in depth-first (pre-order) traverse method. If however, you desire the descendents to be returned in a different ordering, this can be accomplished using a different traversal method, you can supply a C<$visitor> object implementing that traversal type to this method (See B<Tree::Simple::Visitor::BreadthFirstTraversal>, B<Tree::Simple::Visitor::PreOrderTraversal> and B<Tree::Simple::Visitor::PostOrderTraversal>). 114 115=item B<setNodeFilter ($filter_function)> 116 117This 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. 118 119=item B<visit ($tree)> 120 121This 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. 122 123=item B<getAllDescendents> 124 125This method will give back and array of descendents in depth-first order (pre-order) or in the order specified by the C<setTraversalMethod>. If called in scalar context it will give an array reference, in list context it will return a regular array. This method is the same as calling C<getResults>. 126 127=back 128 129=head1 BUGS 130 131None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it. 132 133=head1 CODE COVERAGE 134 135See the B<CODE COVERAGE> section in L<Tree::Simple::VisitorFactory> for more inforamtion. 136 137=head1 SEE ALSO 138 139These 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. 140 141=head1 AUTHOR 142 143stevan little, E<lt>stevan@iinteractive.comE<gt> 144 145=head1 COPYRIGHT AND LICENSE 146 147Copyright 2004, 2005 by Infinity Interactive, Inc. 148 149L<http://www.iinteractive.com> 150 151This library is free software; you can redistribute it and/or modify 152it under the same terms as Perl itself. 153 154=cut 155 156