File Coverage

lib/Tie/HashDefaults.pm
Criterion Covered Total %
statement 50 61 81.9
branch 4 8 50.0
condition 1 3 33.3
subroutine 13 15 86.6
pod 0 2 0.0
total 68 89 76.4


line stmt bran cond sub pod time code
1              
2             #
3             # Strangely enough, the CLEAR method does not actually cause a subsequent
4             # FIRSTKEY to return nil.
5             #
6              
7             package Tie::HashDefaults;
8              
9 1     1   2364 use Carp;
  1         2  
  1         101  
10 1     1   6 use strict;
  1         1  
  1         34  
11 1     1   5 use vars qw( $VERSION );
  1         6  
  1         973  
12             $VERSION = '0.01';
13              
14              
15             sub TIEHASH {
16 1     1   93 my $pkg = shift;
17 1         2 my %values;
18             my @defaults;
19              
20 1 50 33     7 if ( @_ == 1 && UNIVERSAL::isa($_[0],'Tie::HashDefaults') ) {
21             # copy constructor
22 0         0 @defaults = $_[0]->get_defaults_list;
23 0         0 %values = %{ $_[0][1] };
  0         0  
24             }
25             else {
26             # plain list of default sources (hashrefs)
27 3 50       10 @defaults = map {
28 1         4 is_hashref($_) or croak <
29             Bad arg: '$_'\n\tExpected another Tie::HashDefaults (ref), or a list of default sources (hashrefs).
30             EOF
31 3         10 $_
32             } @_;
33             }
34              
35 1         9 bless( [ undef, \%values, \@defaults ], $pkg );
36             }
37              
38             sub is_hashref {
39 3     3 0 10 local $_ = '' . shift;
40 3         17 s/.*=//;
41 3         24 /^HASH\(/
42             }
43              
44             sub get_defaults_list {
45 11     11 0 11 my $self = shift;
46 11         19 $self->_delete_iteration_hash;
47 11         18 $self->[2];
48             }
49              
50             sub _get_sources_list {
51 11     11   17 my $self = shift;
52 11         19 my $deflist = $self->get_defaults_list;
53 11         37 ( $self->[1], @$deflist )
54             }
55              
56             sub _delete_iteration_hash {
57 19     19   27 my $self = shift;
58 19         33 $self->[0] = undef;
59             }
60              
61             sub EXISTS {
62 0     0   0 my( $self, $key ) = @_;
63 0         0 for ( $self->_get_sources_list ) {
64 0 0       0 exists $_->{$key} and return(1);
65             }
66 0         0 return(); # not found
67             }
68              
69             sub FETCH {
70 9     9   53 my( $self, $key ) = @_;
71 9         15 for ( $self->_get_sources_list ) {
72 16 100       69 exists $_->{$key} and return( $_->{$key} );
73             }
74 0         0 return(); # not found
75             }
76              
77             sub DELETE {
78 0     0   0 my( $self, $key ) = @_;
79 0         0 $self->_delete_iteration_hash;
80 0         0 delete $self->[1]{$key};
81             }
82              
83             sub STORE {
84 5     5   36 my( $self, $key, $val ) = @_;
85 5         15 $self->_delete_iteration_hash;
86 5         26 $self->[1]{$key} = $val;
87             }
88              
89             sub CLEAR {
90 1     1   15 my( $self ) = @_;
91 1         3 $self->_delete_iteration_hash;
92 1         2 %{ $self->[1] } = ();
  1         4  
93 1         4 $self
94             }
95              
96             sub FIRSTKEY {
97 2     2   15 my( $self ) = @_;
98 2         6 $self->_delete_iteration_hash;
99 2         2 my %iter;
100 2         47 for ( reverse $self->_get_sources_list ) {
101 8         28 while ( my($k,$v) = each %$_ ) {
102 17         63 $iter{$k} = $v;
103             }
104             }
105 2         4 $self->[0] = \%iter;
106 2         5 each %{$self->[0]}
  2         12  
107             }
108              
109             sub NEXTKEY {
110 9     9   13 my( $self ) = @_;
111 9         10 each %{$self->[0]}
  9         39  
112             }
113              
114             1;
115              
116             __END__