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   24715 use strict;
  18         47  
  18         607  
4 18     18   116 use Data::Hopen::Base;
  18         36  
  18         114  
5              
6             our $VERSION = '0.000017';
7              
8 18     18   12413 use Data::Hopen::Scope qw(:default :internal);
  18         73  
  18         2793  
9 18     18   164 use parent 'Data::Hopen::Scope';
  18         42  
  18         155  
10             use Class::Tiny {
11 155         1683 _content => sub { +{} }, # Our storage
12 18     18   1611 };
  18         39  
  18         241  
13              
14 18     18   4992 use Data::Hopen qw(getparameters);
  18         52  
  18         854  
15             #use Data::Hopen::Util::Data qw(clone);
16 18     18   145 use Set::Scalar;
  18         566  
  18         10190  
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 16290 my $self = shift or croak 'Need an instance';
59 48 100       276 croak "Got an odd number of parameters" if @_%2;
60 47 100       131 return $self unless @_;
61 46         158 my %new = @_;
62 46         137 @{$self->_content}{keys %new} = values %new;
  46         1173  
63 46         167 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 2613 my $self = shift or croak 'Need an instance';
74 44 100       239 croak "Got an odd number of parameters" if @_%2;
75 43 100       110 return unless @_;
76              
77 39         123 my %new = @_;
78 39         183 my $merger = $self->_merger;
79 39         916 $self->_content($merger->merge($self->_content, \%new));
80              
81 39         3371 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 2607 my $self = shift or croak 'Need an instance';
99 4 100       103 my $hrNew = shift or croak 'Need a hash to adopt';
100 3 100       190 croak 'Cannot adopt a non-hash' unless ref $hrNew eq 'HASH';
101 1         27 $self->_content($hrNew);
102 1         8 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   1730 my ($self, %args) = getparameters('self', [qw(retval ; set)], @_);
118 520 50       68095 _set0 $args{set} or croak 'I only support set 0';
119 520         1198 $args{retval}->insert(keys %{$self->_content});
  520         11771  
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   1720 my ($self, %args) = getparameters('self', [qw(name ; set)], @_);
134 532 50       31576 _set0 $args{set} or croak 'I only support set 0';
135              
136 532         11403 my $val = $self->_content->{$args{name}};
137 532 100       3691 return undef unless defined $val;
138 328 100       1324 return ($args{set} eq '*') ? { 0 => $val } : $val;
139             } #_find_here()
140              
141             1;
142             __END__