File Coverage

blib/lib/Template/Plugin/StringTree/Node.pm
Criterion Covered Total %
statement 35 36 97.2
branch 13 20 65.0
condition 2 3 66.6
subroutine 12 12 100.0
pod 0 2 0.0
total 62 73 84.9


line stmt bran cond sub pod time code
1             package Template::Plugin::StringTree::Node;
2              
3             # This package implements the actual nodes in the StringTree.
4             # We need to be very careful not to pollute this namespace with methods.
5              
6 2     2   28 use 5.005;
  2         8  
  2         88  
7 2     2   12 use strict;
  2         3  
  2         67  
8 2     2   11 use Scalar::Util ();
  2         4  
  2         37  
9 2     2   1758 use overload '""' => '__get';
  2         1102  
  2         15  
10              
11 2     2   134 use vars qw{$VERSION %STRING};
  2         3  
  2         145  
12             BEGIN {
13 2     2   5 $VERSION = '0.08';
14              
15             # Data store for the Nodes
16 2         699 %STRING = ();
17             }
18              
19             # Create a new node, with an optional value
20             sub __new {
21 26 50   26   46 my $class = ref $_[0] ? ref shift : shift;
22 26         58 my $self = bless {}, $class;
23              
24 26 100 66     71 if ( defined $_[0] and ! ref $_[0] ) {
25             # The value for this node
26 6         23 $STRING{Scalar::Util::refaddr($self)} = shift;
27             }
28              
29 26         75 $self;
30             }
31              
32             # Get the value for this node
33             sub __get {
34 49 50   49   286 my $self = ref $_[0] ? shift : return undef;
35 49         181 $STRING{Scalar::Util::refaddr($self)};
36             }
37              
38             # Set the value for this node
39             sub __set {
40 1 50   1   3 my $self = ref $_[0] ? shift : return undef;
41 1 50       2 if ( defined $_[0] ) {
42 1         4 $STRING{Scalar::Util::refaddr($self)} = shift;
43             } else {
44 0         0 delete $STRING{Scalar::Util::refaddr($_[0])};
45             }
46              
47 1         3 1;
48             }
49              
50             # Methods compatible with UNIVERSAL will die in a major way.
51             # Fortunately, we can tell if 'isa' and 'can' calls are meant to be genuine
52             # or not. The two-argument form is passed though, the one-argument form
53             # is treated by descending.
54             sub isa {
55 4     4 0 248 my $self = shift;
56 4 100       26 return $self->SUPER::isa(@_) if @_;
57 1 50       6 exists $self->{isa} ? $self->{isa} : undef;
58             }
59             sub can {
60 2     2 0 3 my $self = shift;
61 2 100       14 return $self->SUPER::can(@_) if @_;
62 1 50       8 exists $self->{can} ? $self->{can} : undef;
63             }
64              
65             # Unfortunately, we have no choice but to use this name.
66             # To prevent pollution, we'll throw an error should we ever try to set
67             # a value using a DESTROY segment in a path.
68             sub DESTROY {
69 26 50   26   525 delete $STRING{Scalar::Util::refaddr($_[0])} if ref $_[0];
70             }
71              
72             1;