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   103161 use strict;
  2         21  
  2         61  
4 2     2   13 use warnings;
  2         4  
  2         91  
5              
6             our $VERSION = '1.33';
7              
8 2     2   14 use Scalar::Util qw(blessed);
  2         5  
  2         152  
9              
10             ## class constants
11              
12 2     2   14 use constant RECURSIVE => 0x01;
  2         6  
  2         156  
13 2     2   14 use constant CHILDREN_ONLY => 0x10;
  2         6  
  2         1451  
14              
15             ### constructor
16              
17             sub new {
18 11     11 1 3941 my ($_class, $func, $depth) = @_;
19 11 100       35 if (defined($depth)){
20 4 100 100     44 ($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     41 my $class = ref($_class) || $_class;
25             # if we have not supplied a $func
26             # it is automatically RECURSIVE
27 9 100       27 $depth = RECURSIVE unless defined $func;
28 9   100     36 my $visitor = {
29             depth => $depth || 0
30             };
31 9         18 bless($visitor, $class);
32 9         28 $visitor->_init();
33 9 100       26 if (defined $func) {
34 5         23 $visitor->setNodeFilter($func);
35 3         8 $visitor->includeTrunk(1);
36             }
37 7         20 return $visitor;
38             }
39              
40             ### methods
41              
42             sub _init {
43 9     9   19 my ($self) = @_;
44 9         21 $self->{_include_trunk} = 0;
45 9         19 $self->{_filter_function} = undef;
46 9         18 $self->{_results} = [];
47             }
48              
49             sub includeTrunk {
50 11     11 1 35 my ($self, $boolean) = @_;
51 11 100       39 $self->{_include_trunk} = ($boolean ? 1 : 0) if defined $boolean;
    100          
52 11         29 return $self->{_include_trunk};
53             }
54              
55             # node filter methods
56              
57             sub getNodeFilter {
58 3     3 1 9 my ($self) = @_;
59 3         15 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 113 my ($self, $filter_function) = @_;
69 9 100 100     73 (defined($filter_function) && ref($filter_function) eq "CODE")
70             || die "Insufficient Arguments : filter function argument must be a subroutine reference";
71 5         12 $self->{_filter_function} = $filter_function;
72             }
73              
74             # results methods
75              
76             sub setResults {
77 6     6 1 21 my ($self, @results) = @_;
78 6         39 $self->{results} = \@results;
79             }
80              
81             sub getResults {
82 3     3 1 455 my ($self) = @_;
83             return wantarray ?
84 2         61 @{$self->{results}}
85             :
86 3 100       15 $self->{results};
87             }
88              
89             # visit routine
90             sub visit {
91 10     10 1 1955 my ($self, $tree) = @_;
92 10 100 100     92 (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         12 my @results;
96             my $func;
97 6 100       30 if ($self->{_filter_function}) {
98 4     16   17 $func = sub { push @results => $self->{_filter_function}->(@_) };
  16         33  
99             }
100             else {
101 2     12   16 $func = sub { push @results => $_[0]->getNodeValue() };
  12         37  
102             }
103             # always apply the function
104             # to the tree's node
105              
106 6 100 66     52 $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       37 $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       20 if ($self->{depth} == CHILDREN_ONLY) {
114 1         5 $func->($_) foreach $tree->getAllChildren();
115             }
116             # now store the results we got
117 6         33 $self->setResults(@results);
118             }
119              
120              
121             1;
122              
123             __END__