File Coverage

blib/lib/MouseX/NativeTraits/MethodProvider/HashRef.pm
Criterion Covered Total %
statement 131 178 73.6
branch 37 70 52.8
condition n/a
subroutine 37 38 97.3
pod 17 17 100.0
total 222 303 73.2


line stmt bran cond sub pod time code
1             package MouseX::NativeTraits::MethodProvider::HashRef;
2 7     19   6156 use Mouse;
  7         14  
  7         52  
3              
4             extends qw(MouseX::NativeTraits::MethodProvider);
5              
6             sub generate_keys {
7 6     18 1 110 my($self) = @_;
8 6         34 my $reader = $self->reader;
9              
10             return sub {
11 14 50   26   58 if(@_ != 1) {
        19      
12 0         0 $self->argument_error('keys', 1, 1, scalar @_);
13             }
14 14         20 return keys %{ $reader->( $_[0] ) };
  14         310  
15 6         110 };
16             }
17              
18             sub generate_sorted_keys {
19 1     1 1 41 my($self) = @_;
20 1         14 my $reader = $self->reader;
21              
22             return sub {
23 1 50   1   662 if(@_ != 1) {
24 0         0 $self->argument_error('sorted_keys', 1, 1, scalar @_);
25             }
26 1         2 return sort keys %{ $reader->( $_[0] ) };
  1         10  
27 1         46 };
28             }
29              
30             sub generate_values {
31 6     6 1 108 my($self) = @_;
32 6         52 my $reader = $self->reader;
33              
34             return sub {
35 12 50   12   51 if(@_ != 1) {
        2      
36 0         0 $self->argument_error('values', 1, 1, scalar @_);
37             }
38 12         19 return values %{ $reader->( $_[0] ) };
  12         109  
39 6         83 };
40             }
41              
42             sub generate_kv {
43 5     17 1 80 my($self) = @_;
44 5         14 my $reader = $self->reader;
45              
46             return sub {
47 12 50   22   838 if(@_ != 1) {
48 0         0 $self->argument_error('kv', 1, 1, scalar @_);
49             }
50 12         47 my $hash_ref = $reader->( $_[0] );
51 12         30 return map { [ $_ => $hash_ref->{$_} ] } keys %{ $hash_ref };
  22         302  
  12         73  
52 5         27 };
53             }
54              
55             sub generate_elements {
56 5     27 1 75 my($self) = @_;
57 5         14 my $reader = $self->reader;
58              
59             return sub {
60 10 50   32   9384 if(@_ != 1) {
61 0         0 $self->argument_error('elements', 1, 1, scalar @_);
62             }
63 10         13 return %{ $reader->( $_[0] ) };
  10         71  
64 5         25 };
65             }
66              
67             sub generate_count {
68 6     38 1 139 my($self) = @_;
69 6         32 my $reader = $self->reader;
70              
71             return sub {
72 52 50   74   29653 if(@_ != 1) {
73 0         0 $self->argument_error('count', 1, 1, scalar @_);
74             }
75 52         73 return scalar keys %{ $reader->( $_[0] ) };
  52         324  
76 6         74 };
77             }
78              
79             sub generate_is_empty {
80 5     79 1 90 my($self) = @_;
81 5         24 my $reader = $self->reader;
82              
83             return sub {
84 20 50   80   57156 if(@_ != 1) {
85 0         0 $self->argument_error('is_empty', 1, 1, scalar @_);
86             }
87 20         31 return scalar(keys %{ $reader->( $_[0] ) }) == 0;
  20         128  
88 5         82 };
89             }
90              
91             sub generate_exists {
92 5     85 1 86 my($self) = @_;
93 5         14 my $reader = $self->reader;
94              
95             return sub {
96 22     92   1280 my($instance, $key) = @_;
97 22 50       68 if(@_ != 2) {
98 0         0 $self->argument_error('exists', 2, 2, scalar @_);
99             }
100 22 50       66 defined($key)
101             or $self->meta->throw_error(
102             "Hash keys passed to exists must be defined" );
103 22         127 return exists $reader->( $instance )->{ $key };
104             }
105 5         38 }
106              
107             sub generate_defined {
108 5     97 1 88 my($self) = @_;
109 5         93 my $reader = $self->reader;
110              
111             return sub {
112 12     54   49198 my($instance, $key) = @_;
113 12 50       51 if(@_ != 2) {
114 0         0 $self->argument_error('defined', 2, 2, scalar @_);
115             }
116 12 50       34 defined($key)
117             or $self->meta->throw_error(
118             "Hash keys passed to defined must be defined" );
119 12         79 return defined $reader->( $instance )->{ $key };
120             }
121 5         35 }
122              
123             __PACKAGE__->meta->add_method(generate_get => \&generate_fetch);
124             sub generate_fetch {
125 7     61 1 110 my($self) = @_;
126 7         22 my $reader = $self->reader;
127              
128             return sub {
129 42 50   76   1901 if(@_ < 2) {
130 0         0 $self->argument_error('get', 2, undef, scalar @_);
131             }
132              
133 42         74 my $instance = shift;
134 42         92 foreach my $key(@_) {
135 92 50       247 defined($key)
136             or $self->meta->throw_error(
137             "Hash keys passed to get must be defined" );
138             }
139              
140 42 100       163 if ( @_ == 1 ) {
141 12         290 return $reader->( $instance )->{ $_[0] };
142             }
143             else {
144 30         45 return @{ $reader->($instance) }{@_};
  30         321  
145             }
146 7         62 };
147             }
148              
149              
150             __PACKAGE__->meta->add_method(generate_set => \&generate_store);
151             sub generate_store {
152 12     86 1 196 my($self) = @_;
153              
154 12         75 my $reader = $self->reader;
155 12         298 my $writer = $self->writer;
156              
157 12         260 my $constraint = $self->attr->type_constraint;
158 12         53 my $trigger = $self->attr->trigger;
159              
160             return sub {
161 70     122   110437 my ( $instance, @kv ) = @_;
162 70 50       271 if(@_ < 2) {
163 0         0 $self->argument_error('set', 2, undef, scalar @_);
164             }
165              
166 70         227 my $hash_ref = $reader->($instance);
167 70         115 my %new_value = %{ $hash_ref }; # make a working copy
  70         369  
168 67         140 my @ret_value;
169 67         485 while (my ($key, $value) = splice @kv, 0, 2 ) {
170 88 50       188 defined($key)
171             or $self->meta->throw_error(
172             "Hash keys passed to set must be defined" );
173 88         664 push @ret_value, $new_value{$key} = $value; # change
174             }
175              
176 67 50       905 $constraint->assert_valid(\%new_value) if defined $constraint;
177              
178 51         613 %{ $hash_ref } = %new_value; # commit
  51         184  
179 51 100       208 $trigger->($instance) if defined $trigger;
180              
181 51 100       452 return wantarray ? @ret_value : $ret_value[-1];
182 12         110 };
183             }
184              
185             sub generate_accessor {
186 12     132 1 187 my($self) = @_;
187              
188 12         41 my $reader = $self->reader;
189 12         69 my $writer = $self->writer;
190              
191 12         152 my $constraint = $self->attr->type_constraint;
192 12         39 my $trigger = $self->attr->trigger;
193              
194             return sub {
195 56     162   4542 my($instance, $key, $value) = @_;;
196              
197 56 100       195 if ( @_ == 2 ) { # reader
    100          
198 22 50       59 defined($key)
199             or $self->meta->throw_error(
200             "Hash keys passed to accessor must be defined" );
201 22         421 return $reader->($instance)->{ $key };
202             }
203             elsif ( @_ == 3 ) { # writer
204 24 50       70 defined($key) or $self->meta->throw_error(
205             "Hash keys passed to accessor must be defined" );
206              
207 24         92 my $hash_ref = $reader->($instance);
208 23         68 my %new_value = %{ $hash_ref };
  23         69  
209 23         60 $new_value{$key} = $value;
210 23 50       167 $constraint->assert_valid(\%new_value) if defined $constraint;
211 23         272 %{ $hash_ref } = %new_value;
  23         67  
212 23 100       104 $trigger->($instance) if defined $trigger;
213             }
214             else {
215 10         64 $self->argument_error('accessor', 2, 3, scalar @_);
216             }
217 12         113 };
218             }
219              
220             sub generate_clear {
221 5     167 1 79 my($self) = @_;
222              
223 5         15 my $reader = $self->reader;
224              
225             return sub {
226 10 50   132   41 if(@_ != 1) {
227 0         0 $self->argument_error('clear', 1, 1, scalar @_);
228             }
229 10         21 %{ $reader->( $_[0] ) } = ();
  10         50  
230 5         24 };
231             }
232              
233             sub generate_delete {
234 6     120 1 124 my($self) = @_;
235              
236 6         26 my $reader = $self->reader;
237 6         68 my $trigger = $self->attr->trigger;
238              
239             return sub {
240 21 50   83   10606 if(@_ < 2) {
241 0         0 $self->argument_error('delete', 2, undef, scalar @_);
242             }
243 21         38 my $instance = shift;
244              
245 21         33 my @r = delete @{ $reader->($instance) }{@_};
  21         105  
246 21 100       71 $trigger->($instance) if defined $trigger;
247 21 100       220 return wantarray ? @r : $r[-1];
248 6         50 };
249             }
250              
251             sub generate_for_each_key {
252 0     83 1   my($self) = @_;
253              
254 0           my $reader = $self->reader;
255              
256             return sub {
257 0     30     my($instance, $block) = @_;
258              
259 0 0         if(@_ != 2) {
260 0           $self->argument_error('for_each_key', 2, 2, scalar @_);
261             }
262              
263 0 0         Mouse::Util::TypeConstraints::CodeRef($block)
264             or $instance->meta->throw_error(
265             "The argument passed to for_each_key must be a code reference");
266              
267 0           foreach (keys %{$reader->($instance)}) { # intentional use of $_
  0            
268 0           $block->($_);
269             }
270              
271 0           return $instance;
272 0           };
273             }
274              
275             sub generate_for_each_value {
276 0     30 1   my($self) = @_;
277              
278 0           my $reader = $self->reader;
279              
280             return sub {
281 0     20     my($instance, $block) = @_;
282              
283 0 0         if(@_ != 2) {
284 0           $self->argument_error('for_each_value', 2, 2, scalar @_);
285             }
286              
287 0 0         Mouse::Util::TypeConstraints::CodeRef($block)
288             or $instance->meta->throw_error(
289             "The argument passed to for_each_value must be a code reference");
290              
291 0           foreach (values %{$reader->($instance)}) { # intentional use of $_
  0            
292 0           $block->($_);
293             }
294              
295 0           return $instance;
296 0           };
297             }
298              
299             sub generate_for_each_pair {
300 0     20 1   my($self) = @_;
301              
302 0           my $reader = $self->reader;
303              
304             return sub {
305 0     0     my($instance, $block) = @_;
306              
307 0 0         if(@_ != 2) {
308 0           $self->argument_error('for_each_pair', 2, 2, scalar @_);
309             }
310              
311 0 0         Mouse::Util::TypeConstraints::CodeRef($block)
312             or $instance->meta->throw_error(
313             "The argument passed to for_each_pair must be a code reference");
314              
315 0           my $hash_ref = $reader->($instance);
316 0           foreach my $key(keys %{$hash_ref}){
  0            
317 0           $block->($key, $hash_ref->{$key});
318             }
319              
320 0           return $instance;
321 0           };
322             }
323              
324              
325 7     19   30182 no Mouse;
  7         16  
  7         57  
326             __PACKAGE__->meta->make_immutable();
327              
328             __END__