File Coverage

blib/lib/Bubblegum/Object/Hash.pm
Criterion Covered Total %
statement 143 145 98.6
branch 19 30 63.3
condition 1 3 33.3
subroutine 36 36 100.0
pod 30 30 100.0
total 229 244 93.8


line stmt bran cond sub pod time code
1             # ABSTRACT: Common Methods for Operating on Hash References
2             package Bubblegum::Object::Hash;
3              
4 36     36   20276 use 5.10.0;
  36         107  
  36         1495  
5 36     36   160 use namespace::autoclean;
  36         48  
  36         190  
6              
7 36     36   1902 use Bubblegum::Class 'with';
  36         52  
  36         187  
8 36     36   25769 use Bubblegum::Constraints -isas, -types;
  36         61  
  36         400  
9              
10             with 'Bubblegum::Object::Role::Defined';
11             with 'Bubblegum::Object::Role::Keyed';
12             with 'Bubblegum::Object::Role::Ref';
13             with 'Bubblegum::Object::Role::Coercive';
14             with 'Bubblegum::Object::Role::Output';
15              
16 36     36   175225 use Clone 'clone';
  36         79415  
  36         96458  
17              
18             our @ISA = (); # non-object
19              
20             our $VERSION = '0.45'; # VERSION
21              
22             sub aslice {
23 2     2 1 2972 goto &array_slice;
24             }
25              
26             sub array_slice {
27 4     4 1 3257 my $self = CORE::shift;
28 4         6 my @keys = map { type_string $_ } @_;
  8         527  
29 4         83 return [@{$self}{@keys}];
  4         23  
30             }
31              
32             sub clear {
33 1     1 1 3159 goto ∅
34             }
35              
36             sub defined {
37 3     3 1 3533 my $self = CORE::shift;
38 3         9 my $key = type_string CORE::shift;
39 3         116 return CORE::defined $self->{$key};
40             }
41              
42             sub delete {
43 1     1 1 3161 my $self = CORE::shift;
44 1         4 my $key = type_string CORE::shift;
45 1         42 return CORE::delete $self->{$key};
46             }
47              
48             sub each {
49 1     1 1 3177 my $self = CORE::shift;
50 1         2 my $code = CORE::shift;
51              
52 1 50       6 $code = $code->codify if isa_string $code;
53 1         5 type_coderef $code;
54              
55 1         372 for my $key (CORE::keys %$self) {
56 4         16 $code->($key, $self->{$key}, @_);
57             }
58              
59 1         5 return $self;
60             }
61              
62             sub each_key {
63 1     1 1 3277 my $self = CORE::shift;
64 1         2 my $code = CORE::shift;
65              
66 1 50       5 $code = $code->codify if isa_string $code;
67 1         4 type_coderef $code;
68              
69 1         36 $code->($_, @_) for CORE::keys %$self;
70 1         14 return $self;
71             }
72              
73             sub each_n_values {
74 1     1 1 3177 my $self = CORE::shift;
75 1 50       7 my $number = $_[0] ? type_number CORE::shift : 2;
76 1         346 my $code = CORE::shift;
77              
78 1 50       6 $code = $code->codify if isa_string $code;
79 1         4 type_coderef $code;
80              
81 1         35 my @values = CORE::values %$self;
82 1         7 $code->(CORE::splice(@values, 0, $number), @_) while @values;
83 1         10 return $self;
84             }
85              
86             sub each_value {
87 1     1 1 3144 my $self = CORE::shift;
88 1         3 my $code = CORE::shift;
89              
90 1 50       5 $code = $code->codify if isa_string $code;
91 1         3 type_coderef $code;
92              
93 1         36 $code->($_, @_) for CORE::values %$self;
94 1         13 return $self;
95             }
96              
97             sub empty {
98 2     2 1 3222 my $self = CORE::shift;
99 2         8 CORE::delete @$self{CORE::keys%$self};
100 2         4 return $self;
101             }
102              
103             sub exists {
104 2     2 1 3673 my $self = CORE::shift;
105 2         7 my $key = type_string CORE::shift;
106 2         75 return CORE::exists $self->{$key};
107             }
108              
109             sub filter_exclude {
110 1     1 1 2979 my $self = CORE::shift;
111 1         3 my @keys = map { type_string $_ } @_;
  2         37  
112 1         23 my %i = map { $_ => type_string $_ } @keys;
  2         23  
113              
114 2 50       9 return {CORE::map { CORE::exists $self->{$_} ? ($_ => $self->{$_}) : () }
  4         5  
115 1         23 CORE::grep { not CORE::exists $i{$_} } CORE::keys %$self};
116             }
117              
118             sub filter_include {
119 1     1 1 3124 my $self = CORE::shift;
120 1         3 my @keys = map { type_string $_ } @_;
  2         37  
121              
122 1 50       21 return {CORE::map { CORE::exists $self->{$_} ? ($_ => $self->{$_}) : () }
  2         9  
123             @keys};
124             }
125              
126             sub get {
127 1     1 1 3215 my $self = CORE::shift;
128 1         4 my $key = type_string CORE::shift;
129 1         37 return $self->{$key};
130             }
131              
132             sub hash_slice {
133 2     2 1 3082 my $self = CORE::shift;
134 2         4 my @keys = map { type_string $_ } @_;
  4         69  
135 2         43 return {CORE::map { $_ => $self->{$_} } @keys};
  4         11  
136             }
137              
138             sub hslice {
139 1     1 1 3276 goto &hash_slice;
140             }
141              
142             sub invert {
143 1     1 1 3163 my $self = CORE::shift;
144 1         2 my $temp = {};
145              
146 1         4 for (CORE::keys %$self) {
147 6 100       17 CORE::defined $self->{$_} ?
148             $temp->{CORE::delete $self->{$_}} = $_ :
149             CORE::delete $self->{$_};
150             }
151              
152 1         3 for (CORE::keys %$temp) {
153 5         7 $self->{$_} = CORE::delete $temp->{$_};
154             }
155              
156 1         3 return $self;
157             }
158              
159             sub iterator {
160 1     1 1 3464 my $self = CORE::shift;
161 1         3 my @keys = CORE::keys %{$self};
  1         5  
162              
163 1         2 my $i = 0;
164             return sub {
165 5 100   5   12 return undef if $i > $#keys;
166 4         10 return $self->{$keys[$i++]};
167             }
168 1         6 }
169              
170             sub keys {
171 1     1 1 3165 my $self = CORE::shift;
172 1         5 return [CORE::keys %$self];
173             }
174              
175             sub lookup {
176 4     4 1 3195 my $self = CORE::shift;
177 4         12 my $key = type_string CORE::shift;
178 4         138 my @keys = CORE::split /\./, $key;
179 4         5 my $node = $self;
180 4         6 for my $key (@keys) {
181 7 50       15 if ('HASH' eq CORE::ref $node) {
182 7 100       18 return undef unless CORE::exists $node->{$key};
183 6         10 $node = $node->{$key};
184             }
185             else {
186 0         0 return undef;
187             }
188             }
189 3         18 return $node;
190             }
191              
192             sub pairs {
193 1     1 1 3062 goto &pairs_array;
194             }
195              
196             sub pairs_array {
197 2     2 1 5174 my $self = CORE::shift;
198 2         7 return [CORE::map { [ $_, $self->{$_} ] } CORE::keys %$self];
  8         26  
199             }
200              
201             sub print {
202 2     2 1 3214 my $self = CORE::shift;
203 2         16 return CORE::print %$self, @_;
204             }
205              
206             sub list {
207 1     1 1 5100 my $self = CORE::shift;
208 1         5 return %$self;
209             }
210              
211             sub merge {
212 1     1 1 3176 my $self = CORE::shift;
213 1         6 my @hashes = CORE::map type_hashref($_), @_;
214              
215 1 50       384 return clone $self unless @hashes;
216 1 50       4 return clone merge($self, merge(@hashes)) if @hashes > 1;
217              
218 1         2 my ($right) = @hashes;
219              
220 1         6 my %merge = %$self;
221 1         3 for my $key (CORE::keys %$right) {
222 2         4 my ($hr, $hl) = CORE::map { ref $$_{$key} eq 'HASH' }
  4         7  
223             $right, $self;
224 2 50 33     7 if ($hr and $hl){
225 0         0 $merge{$key} = merge($self->{$key}, $right->{$key})
226             }
227             else {
228 2         5 $merge{$key} = $right->{$key}
229             }
230             }
231              
232 1         21 return clone \%merge;
233             }
234              
235             sub reset {
236 1     1 1 3012 my $self = CORE::shift;
237 1         5 @$self{CORE::keys%$self}=();
238 1         3 return $self;
239             }
240              
241             sub reverse {
242 1     1 1 3185 my $self = CORE::shift;
243 1         2 my $temp = {};
244              
245 1         5 for (CORE::keys %$self) {
246 5 100       13 $temp->{$_} = $self->{$_} if defined $self->{$_};
247             }
248              
249 1         7 return {CORE::reverse %$temp};
250             }
251              
252             sub say {
253 2     2 1 3185 my $self = CORE::shift;
254 2         175 return print(%$self, @_, "\n");
255             }
256              
257             sub set {
258 3     3 1 3085 my $self = CORE::shift;
259 3         10 my $key = type_string CORE::shift;
260 3         103 return $self->{$key} = CORE::shift;
261             }
262              
263             sub values {
264 1     1 1 3325 my $self = CORE::shift;
265 1         4 return [CORE::values %$self];
266             }
267              
268             1;
269              
270             __END__