File Coverage

blib/lib/Tree/Simple/Visitor.pm
Criterion Covered Total %
statement 59 59 100.0
branch 26 26 100.0
condition 17 20 85.0
subroutine 16 16 100.0
pod 8 8 100.0
total 126 129 97.6


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