File Coverage

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 19     19   34122 use strict;
  19         42  
  19         878  
4 19     19   117 use Data::Hopen::Base;
  19         41  
  19         277  
5              
6             our $VERSION = '0.000021';
7              
8 19     19   14024 use Data::Hopen::Scope qw(:default :internal);
  19         104  
  19         3395  
9 19     19   166 use parent 'Data::Hopen::Scope';
  19         37  
  19         192  
10             use Class::Tiny {
11 155         1824 _content => sub { +{} }, # Our storage
12 19     19   2300 };
  19         37  
  19         226  
13              
14 19     19   6322 use Data::Hopen qw(getparameters);
  19         63  
  19         1153  
15             #use Data::Hopen::Util::Data qw(clone);
16 19     19   130 use Set::Scalar;
  19         38  
  19         12893  
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 1408262 my $self = shift or croak 'Need an instance';
59 48 100       2771 croak "Got an odd number of parameters" if @_%2;
60 47 100       149 return $self unless @_;
61 46         183 my %new = @_;
62 46         138 @{$self->_content}{keys %new} = values %new;
  46         1429  
63 46         211 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 7256 my $self = shift or croak 'Need an instance';
74 44 100       317 croak "Got an odd number of parameters" if @_%2;
75 43 100       121 return unless @_;
76              
77 39         141 my %new = @_;
78 39         218 my $merger = $self->_merger;
79 39         1298 $self->_content($merger->merge($self->_content, \%new));
80              
81 39         4137 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 3681 my $self = shift or croak 'Need an instance';
99 4 100       218 my $hrNew = shift or croak 'Need a hash to adopt';
100 3 100       361 croak 'Cannot adopt a non-hash' unless ref $hrNew eq 'HASH';
101 1         92 $self->_content($hrNew);
102 1         9 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   1958 my ($self, %args) = getparameters('self', [qw(retval ; set)], @_);
118 520 50       76385 _set0 $args{set} or croak 'I only support set 0';
119 520         1193 $args{retval}->insert(keys %{$self->_content});
  520         15812  
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   1972 my ($self, %args) = getparameters('self', [qw(name ; set)], @_);
134 532 50       34576 _set0 $args{set} or croak 'I only support set 0';
135              
136 532         15973 my $val = $self->_content->{$args{name}};
137 532 100       4195 return undef unless defined $val;
138 328 100       1446 return ($args{set} eq '*') ? { 0 => $val } : $val;
139             } #_find_here()
140              
141             1;
142             __END__