File Coverage

blib/lib/Tie/Hash/Vivify.pm
Criterion Covered Total %
statement 39 39 100.0
branch 4 4 100.0
condition 5 6 83.3
subroutine 13 13 100.0
pod 1 1 100.0
total 62 63 98.4


line stmt bran cond sub pod time code
1             package Tie::Hash::Vivify;
2              
3 2     2   35131 use 5.006001;
  2         5  
4 2     2   9 use strict;
  2         4  
  2         50  
5 2     2   8 use warnings;
  2         8  
  2         930  
6              
7             our $VERSION = "1.02";
8              
9             sub new {
10 11     11 1 63 my ($class, $defsub, %params) = @_;
11 11         40 tie my %hash => $class, $defsub, %params;
12 11         21 \%hash;
13             }
14              
15             sub TIEHASH {
16 12     12   14 my ($class, $defsub, %params) = @_;
17 12         34 bless [{}, $defsub, \%params], $class;
18             }
19              
20             sub FETCH {
21 45     45   2454 my ($self, $key) = @_;
22 45         64 my ($hash, $defsub) = @$self;
23 45 100       61 if (exists $hash->{$key}) {
24 32         86 $hash->{$key};
25             }
26             else {
27 13         20 $hash->{$key} = $defsub->();
28             }
29             }
30              
31             sub STORE {
32 12     12   841 my($self, $key, $value) = @_;
33            
34             # print STDERR "ref(\$value): ".ref($value)."\n";
35             # print STDERR "infect_children: ".($self->[2]->{infect_children} ? 1 : 0)."\n";
36             # if(ref($value) eq 'HASH') { print STDERR "tied: ".!!tied(%{$value})."\n" }
37             # print STDERR "\n";
38 12 100 66     57 if(
      100        
39             ref($value) eq 'HASH' &&
40             $self->[2]->{infect_children} &&
41 8         27 !tied(%{$value})
42             # this would re-tie anything except a THV
43             # !(tied(%{$value}) && tied(%{$value})->isa(__PACKAGE__))
44             ) {
45 5         6 $self->[0]->{$key} = __PACKAGE__->new($self->[1], %{$self->[2]});
  5         16  
46 5         6 $self->[0]->{$key}->{$_} = $value->{$_} foreach(keys(%{$value}));
  5         17  
47 5         10 $self->[0]->{$key};
48             } else {
49 7         23 $self->[0]->{$key} = $value;
50             }
51             }
52              
53             # copied from Tie::ExtraHash in perl-5.10.1/lib/Tie/Hash.pm
54 12     12   1080 sub FIRSTKEY { my $a = scalar keys %{$_[0][0]}; each %{$_[0][0]} }
  12         19  
  12         10  
  12         33  
55 17     17   10 sub NEXTKEY { each %{$_[0][0]} }
  17         30  
56 19     19   541 sub EXISTS { exists $_[0][0]->{$_[1]} }
57 1     1   4 sub DELETE { delete $_[0][0]->{$_[1]} }
58 1     1   1 sub CLEAR { %{$_[0][0]} = () }
  1         4  
59 1     1   1 sub SCALAR { scalar %{$_[0][0]} }
  1         6  
60              
61             1;
62              
63              
64             =head1 NAME
65              
66             Tie::Hash::Vivify - Create hashes that autovivify in interesting ways.
67              
68             =head1 DESCRIPTION
69              
70             This module implements a hash where if you read a key that doesn't exist, it
71             will call a code reference to fill that slot with a value.
72              
73             =head1 SYNOPSIS
74              
75             use Tie::Hash::Vivify;
76              
77             my $default = 0;
78             tie my %hash => 'Tie::Hash::Vivify', sub { "default" . $default++ };
79             print $hash{foo}; # default0
80             print $hash{bar}; # default1
81             print $hash{foo}; # default0
82             $hash{baz} = "hello";
83             print $hash{baz}; # hello
84              
85             my $hashref = Tie::Hash::Vivify->new(sub { "default" });
86             $hashref->{foo}; # default
87             # ...
88              
89             =head1 OBJECT-ORIENTED INTERFACE
90              
91             You can also create your magic hash in an objecty way:
92              
93             =head2 new
94              
95             my $hashref = Tie::Hash::Vivify->new(sub { "my default" });
96              
97             =head1 "INFECTING" CHILD HASHES
98              
99             By default, hashes contained within your hash do *not* inherit magical
100             vivification behaviour. If you want them to, then pass some extra
101             params thus:
102              
103             tie my %hash => 'Tie::Hash::Vivify', sub { "default" . $default++ }, infect_children => 1;
104              
105             my $hashref = Tie::Hash::Vivify->new(sub { "my default" }, infect_children => 1);
106              
107             This will not, however, work if the child you insert is already tied - that
108             would require re-tieing it, which would lose whatever magic behaviour the
109             original had.
110              
111             =head1 AUTHORS
112              
113             Luke Palmer, lrpalmer gmail com (original author)
114              
115             David Cantrell Edavid@cantrell.org.ukE (current maintainer)
116              
117             =head1 COPYRIGHT AND LICENSE
118              
119             Copyright (C) 2005 by Luke Palmer
120              
121             Some parts Copyright 2010 David Cantrell Edavid@cantrell.org.ukE.
122              
123             This software is free-as-in-speech software, and may be used,
124             distributed, and modified under the terms of either the GNU
125             General Public Licence version 2 or the Artistic Licence. It's
126             up to you which one you use. The full text of the licences can
127             be found in the files GPL2.txt and ARTISTIC.txt, respectively.
128              
129             =cut