File Coverage

blib/lib/Tree/Simple/Visitor.pm
Criterion Covered Total %
statement 59 59 100.0
branch 26 26 100.0
condition 15 20 75.0
subroutine 16 16 100.0
pod 8 8 100.0
total 124 129 96.1


line stmt bran cond sub pod time code
1             package Tree::Simple::Visitor;
2              
3 2     2   18184 use strict;
  2         3  
  2         50  
4 2     2   7 use warnings;
  2         2  
  2         68  
5              
6             our $VERSION = '1.31';
7              
8 2     2   17 use Scalar::Util qw(blessed);
  2         2  
  2         134  
9              
10             ## class constants
11              
12 2     2   7 use constant RECURSIVE => 0x01;
  2         3  
  2         103  
13 2     2   6 use constant CHILDREN_ONLY => 0x10;
  2         3  
  2         1048  
14              
15             ### constructor
16              
17             sub new {
18 11     11 1 1968 my ($_class, $func, $depth) = @_;
19 11 100       30 if (defined($depth)){
20 4 100 100     52 ($depth =~ /\d+/ && ($depth == RECURSIVE || $depth == CHILDREN_ONLY))
      66        
21             || die "Insufficient Arguments : Depth arguement must be either ".
22             "RECURSIVE or CHILDREN_ONLY";
23             }
24 9   33     39 my $class = ref($_class) || $_class;
25             # if we have not supplied a $func
26             # it is automatically RECURSIVE
27 9 100       15 $depth = RECURSIVE unless defined $func;
28 9   100     32 my $visitor = {
29             depth => $depth || 0
30             };
31 9         11 bless($visitor, $class);
32 9         17 $visitor->_init();
33 9 100       16 if (defined $func) {
34 5         7 $visitor->setNodeFilter($func);
35 3         5 $visitor->includeTrunk(1);
36             }
37 7         13 return $visitor;
38             }
39              
40             ### methods
41              
42             sub _init {
43 9     9   10 my ($self) = @_;
44 9         15 $self->{_include_trunk} = 0;
45 9         11 $self->{_filter_function} = undef;
46 9         13 $self->{_results} = [];
47             }
48              
49             sub includeTrunk {
50 11     11 1 17 my ($self, $boolean) = @_;
51 11 100       24 $self->{_include_trunk} = ($boolean ? 1 : 0) if defined $boolean;
    100          
52 11         21 return $self->{_include_trunk};
53             }
54              
55             # node filter methods
56              
57             sub getNodeFilter {
58 3     3 1 5 my ($self) = @_;
59 3         12 return $self->{_filter_function};
60             }
61              
62             sub clearNodeFilter {
63 1     1 1 2 my ($self) = @_;
64 1         2 $self->{_filter_function} = undef;
65             }
66              
67             sub setNodeFilter {
68 9     9 1 60 my ($self, $filter_function) = @_;
69 9 100 100     76 (defined($filter_function) && ref($filter_function) eq "CODE")
70             || die "Insufficient Arguments : filter function argument must be a subroutine reference";
71 5         7 $self->{_filter_function} = $filter_function;
72             }
73              
74             # results methods
75              
76             sub setResults {
77 6     6 1 13 my ($self, @results) = @_;
78 6         29 $self->{results} = \@results;
79             }
80              
81             sub getResults {
82 3     3 1 235 my ($self) = @_;
83             return wantarray ?
84 2         12 @{$self->{results}}
85             :
86 3 100       12 $self->{results};
87             }
88              
89             # visit routine
90             sub visit {
91 10     10 1 1073 my ($self, $tree) = @_;
92 10 100 100     87 (blessed($tree) && $tree->isa("Tree::Simple"))
93             || die "Insufficient Arguments : You must supply a valid Tree::Simple object";
94             # get all things set up
95 6         8 my @results;
96             my $func;
97 6 100       10 if ($self->{_filter_function}) {
98 4     16   13 $func = sub { push @results => $self->{_filter_function}->(@_) };
  16         23  
99             }
100             else {
101 2     12   8 $func = sub { push @results => $_[0]->getNodeValue() };
  12         25  
102             }
103             # always apply the function
104             # to the tree's node
105              
106 6 100 33     22 $func->($tree) if (defined($self->{_include_trunk}) && $self->{_include_trunk});
107              
108             # then recursively to all its children
109             # if the object is configured that way
110 6 100       29 $tree->traverse($func) if ($self->{depth} == RECURSIVE);
111             # or just visit its immediate children
112             # if the object is configured that way
113 6 100       15 if ($self->{depth} == CHILDREN_ONLY) {
114 1         3 $func->($_) foreach $tree->getAllChildren();
115             }
116             # now store the results we got
117 6         16 $self->setResults(@results);
118             }
119              
120              
121             1;
122              
123             __END__