File Coverage

blib/lib/Data/Hopen/Scope/Hash.pm
Criterion Covered Total %
statement 50 50 100.0
branch 24 26 92.3
condition n/a
subroutine 12 12 100.0
pod 3 3 100.0
total 89 91 97.8


line stmt bran cond sub pod time code
1             # Data::Hopen::Scope::Hash - a hash-based nested key-value store based
2             package Data::Hopen::Scope::Hash;
3 18     18   25065 use strict;
  18         40  
  18         561  
4 18     18   98 use Data::Hopen::Base;
  18         39  
  18         111  
5              
6             our $VERSION = '0.000019';
7              
8 18     18   12207 use Data::Hopen::Scope qw(:default :internal);
  18         60  
  18         2448  
9 18     18   143 use parent 'Data::Hopen::Scope';
  18         40  
  18         131  
10             use Class::Tiny {
11 155         1506 _content => sub { +{} }, # Our storage
12 18     18   1591 };
  18         42  
  18         187  
13              
14 18     18   4758 use Data::Hopen qw(getparameters);
  18         41  
  18         892  
15             #use Data::Hopen::Util::Data qw(clone);
16 18     18   114 use Set::Scalar;
  18         557  
  18         9968  
17             #use Sub::ScopeFinalizer qw(scope_finalizer);
18              
19             # Docs {{{1
20              
21             =head1 NAME
22              
23             Data::Hopen::Scope::Hash - a hash-based nested key-value store
24              
25             =head1 SYNOPSIS
26              
27             This class implements L using a single hash table as the
28             storage. It only supports one set of data (L),
29             which is named C<0>.
30              
31             =head1 ATTRIBUTES
32              
33             =head2 outer
34              
35             The fallback C for looking up names not found in this C.
36             If non is provided, it is C, and no fallback will happen.
37              
38             =head2 name
39              
40             Not used, but provided so you can use L to make Scopes.
41              
42             =head1 METHODS
43              
44             =cut
45              
46             # }}}1
47              
48             =head2 put
49              
50             Add key-value pairs to this scope. See L. In this
51             particular implementation, the last-added value for a particular key wins.
52              
53             TODO add $set option once it's added to D::H::Scope::put().
54              
55             =cut
56              
57             sub put {
58 49 100   49 1 18227 my $self = shift or croak 'Need an instance';
59 48 100       269 croak "Got an odd number of parameters" if @_%2;
60 47 100       117 return $self unless @_;
61 46         159 my %new = @_;
62 46         142 @{$self->_content}{keys %new} = values %new;
  46         1062  
63 46         165 return $self;
64             } #add()
65              
66             =head2 merge
67              
68             Merge in values. See L.
69              
70             =cut
71              
72             sub merge {
73 45 100   45 1 2663 my $self = shift or croak 'Need an instance';
74 44 100       247 croak "Got an odd number of parameters" if @_%2;
75 43 100       104 return unless @_;
76              
77 39         117 my %new = @_;
78 39         145 my $merger = $self->_merger;
79 39         863 $self->_content($merger->merge($self->_content, \%new));
80              
81 39         3200 return $self;
82             } #merge()
83              
84             =head2 adopt_hash
85              
86             Takes over the given hash to be the new contents of the Scope::Hash.
87             Usage example:
88              
89             $scope->adopt_hash({ foo => 42 });
90              
91             The scope uses exactly the hash passed, not a clone of it. If this is not
92             applicable to a subclass, that subclass should override it as C<...> or an
93             express C.
94              
95             =cut
96              
97             sub adopt_hash {
98 5 100   5 1 2561 my $self = shift or croak 'Need an instance';
99 4 100       114 my $hrNew = shift or croak 'Need a hash to adopt';
100 3 100       209 croak 'Cannot adopt a non-hash' unless ref $hrNew eq 'HASH';
101 1         26 $self->_content($hrNew);
102 1         6 return $self;
103             } #adopt_hash()
104              
105             =head2 _names_here
106              
107             Populates a L with the names of the items stored in this Scope,
108             but B any outer Scope. Called as:
109              
110             $scope->_names_here($retval[, $set]);
111              
112             No return value.
113              
114             =cut
115              
116             sub _names_here {
117 520     520   1709 my ($self, %args) = getparameters('self', [qw(retval ; set)], @_);
118 520 50       66047 _set0 $args{set} or croak 'I only support set 0';
119 520         1144 $args{retval}->insert(keys %{$self->_content});
  520         11393  
120             } #_names_here()
121              
122             =head2 _find_here
123              
124             Looks for a given item in this scope, but B any outer scope. Called as:
125              
126             $scope->_find_here($name[, $set])
127              
128             Returns the value, or C if not found.
129              
130             =cut
131              
132             sub _find_here {
133 532     532   1639 my ($self, %args) = getparameters('self', [qw(name ; set)], @_);
134 532 50       31129 _set0 $args{set} or croak 'I only support set 0';
135              
136 532         10610 my $val = $self->_content->{$args{name}};
137 532 100       3529 return undef unless defined $val;
138 328 100       1356 return ($args{set} eq '*') ? { 0 => $val } : $val;
139             } #_find_here()
140              
141             1;
142             __END__