File Coverage

blib/lib/Rose/Object/MakeMethods/Generic.pm
Criterion Covered Total %
statement 210 244 86.0
branch 173 242 71.4
condition 43 71 60.5
subroutine 34 36 94.4
pod 4 4 100.0
total 464 597 77.7


line stmt bran cond sub pod time code
1             package Rose::Object::MakeMethods::Generic;
2              
3 4     5   12795 use strict;
  4         8  
  4         140  
4              
5 4     4   21 use Carp();
  4         9  
  4         120  
6              
7             our $VERSION = '0.859';
8              
9 4     4   4576 use Rose::Object::MakeMethods;
  4         8  
  4         25  
10             our @ISA = qw(Rose::Object::MakeMethods);
11              
12             our $Have_CXSA;
13              
14             TRY:
15             {
16             local $@;
17              
18             eval
19             {
20             require Class::XSAccessor;
21              
22             (my $version = $Class::XSAccessor::VERSION) =~ s/_//g;
23              
24             unless($version >= 0.14)
25             {
26             die "Class::XSAccessor $Class::XSAccessor::VERSION is too old";
27             }
28             };
29              
30             $Have_CXSA = $@ ? 0 : 1;
31             }
32              
33             our $Debug = 0;
34              
35             sub scalar
36             {
37 8     8 1 17 my($class, $name, $args) = @_;
38              
39 8         13 my %methods;
40              
41 8   33     46 my $key = $args->{'hash_key'} || $name;
42 8   100     51 my $interface = $args->{'interface'} || 'get_set';
43              
44 8 100       44 if($interface eq 'get_set_init')
    50          
45             {
46 2   33     15 my $init_method = $args->{'init_method'} || "init_$name";
47              
48             $methods{$name} = sub
49             {
50 6 100   6   3277 return $_[0]->{$key} = $_[1] if(@_ > 1);
51              
52 4 100       36 return defined $_[0]->{$key} ? $_[0]->{$key} :
53             ($_[0]->{$key} = $_[0]->$init_method());
54             }
55 2         20 }
56             elsif($interface eq 'get_set')
57             {
58 6 100 66     50 if($Have_CXSA && !$ENV{'ROSE_OBJECT_NO_CLASS_XSACCESOR'})
59             {
60             $methods{$name} =
61             {
62             make_method => sub
63             {
64 4     4   11 my($name, $target_class, $options) = @_;
65              
66 4 50       14 $Debug && warn "Class::XSAccessor make method ($name => $key) in $target_class\n";
67              
68 4 50       42 Class::XSAccessor->import(
69             accessors => { $name => $key },
70             class => $target_class,
71             replace => $options->{'override_existing'} ? 1 : 0);
72             },
73 5         46 };
74             }
75             else
76             {
77             $methods{$name} = sub
78             {
79 3 100   3   661 return $_[0]->{$key} = $_[1] if(@_ > 1);
80 2         10 return $_[0]->{$key};
81             }
82 1         8 }
83             }
84 0         0 else { Carp::croak "Unknown interface: $interface" }
85              
86 8         36 return \%methods;
87             }
88              
89             sub boolean
90             {
91 8     8 1 18 my($class, $name, $args) = @_;
92              
93 8         11 my %methods;
94              
95 8   33     46 my $key = $args->{'hash_key'} || $name;
96 8   100     54 my $interface = $args->{'interface'} || 'get_set';
97              
98 8 100       30 if($interface eq 'get_set_init')
    50          
99             {
100 2   33     12 my $init_method = $args->{'init_method'} || "init_$name";
101              
102             $methods{$name} = sub
103             {
104 6 50   6   32 return $_[0]->{$key} = $_[1] ? 1 : 0 if(@_ > 1);
    100          
105              
106 4 50       33 return defined $_[0]->{$key} ? $_[0]->{$key} :
    100          
107             ($_[0]->{$key} = $_[0]->$init_method() ? 1 : 0);
108             }
109 2         13 }
110             elsif($interface eq 'get_set')
111             {
112 6 100       15 if(exists $args->{'default'})
113             {
114 4 100       16 if($args->{'default'})
115             {
116             $methods{$name} = sub
117             {
118 2 0   2   13 return $_[0]->{$key} = $_[1] ? 1 : 0 if(@_ > 1);
    50          
119 2 50       20 return defined $_[0]->{$key} ? $_[0]->{$key} : ($_[0]->{$key} = 1)
120             }
121 2         13 }
122             else
123             {
124             $methods{$name} = sub
125             {
126 2 0   2   113 return $_[0]->{$key} = $_[1] ? 1 : 0 if(@_ > 1);
    50          
127 2 50       22 return defined $_[0]->{$key} ? $_[0]->{$key} : ($_[0]->{$key} = 0)
128             }
129 2         14 }
130             }
131             else
132             {
133             $methods{$name} = sub
134             {
135 12 100   12   66 return $_[0]->{$key} = $_[1] ? 1 : 0 if(@_ > 1);
    100          
136 6         31 return $_[0]->{$key};
137             }
138 2         15 }
139             }
140 0         0 else { Carp::croak "Unknown interface: $interface" }
141              
142 8         29 return \%methods;
143             }
144              
145             sub hash
146             {
147 30     30 1 57 my($class, $name, $args) = @_;
148              
149 30         34 my %methods;
150              
151 30   66     107 my $key = $args->{'hash_key'} || $name;
152 30   100     93 my $interface = $args->{'interface'} || 'get_set';
153              
154 30 100       1575 if($interface eq 'get_set_init')
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
155             {
156 2   33     13 my $init_method = $args->{'init_method'} || "init_$name";
157              
158             $methods{$name} = sub
159             {
160 16     16   3893 my($self) = shift;
161              
162             # If called with no arguments, return hash contents
163 16 100       48 unless(@_)
164             {
165 10 100       45 $self->{$key} = $self->$init_method() unless(defined $self->{$key});
166 10 100       50 return wantarray ? %{$self->{$key}} : $self->{$key};
  6         32  
167             }
168              
169             # If called with a hash ref, set value
170 6 100 100     131 if(@_ == 1 && ref $_[0] eq 'HASH')
171             {
172 2         7 $self->{$key} = $_[0];
173             }
174             else
175             {
176             # If called with an index, get that value, or a slice for array refs
177 4 100       18 if(@_ == 1)
178             {
179             # Initialize hash if undefined
180 2 50       25 $self->{$key} = $self->$init_method() unless(defined $self->{$key});
181              
182 2 50       29 return ref $_[0] eq 'ARRAY' ? @{$self->{$key}}{@{$_[0]}} :
  0         0  
  0         0  
183             $self->{$key}{$_[0]};
184             }
185              
186             # Push on new values and return complete set
187 2 50       10 Carp::croak "Odd number of items in assigment to $name" if(@_ % 2);
188              
189 2         18 while(@_)
190             {
191 4         8 local $_ = shift;
192 4         18 $self->{$key}{$_} = shift;
193             }
194             }
195              
196 4 50       26 return wantarray ? %{$self->{$key}} : $self->{$key};
  0         0  
197             }
198 2         25 }
199             elsif($interface eq 'get_set_inited')
200             {
201             $methods{$name} = sub
202             {
203 12     12   2016 my($self) = shift;
204              
205             # If called with no arguments, return hash contents
206 12 100       33 unless(@_)
207             {
208 8 100       26 $self->{$key} = {} unless(defined $self->{$key});
209 8 100       27 return wantarray ? %{$self->{$key}} : $self->{$key};
  4         38  
210             }
211              
212             # If called with a hash ref, set value
213 4 100 66     26 if(@_ == 1 && ref $_[0] eq 'HASH')
214             {
215 2         48 $self->{$key} = $_[0];
216             }
217             else
218             {
219             # If called with an index, get that value, or a slice for array refs
220 2 50       11 if(@_ == 1)
221             {
222 0 0       0 return ref $_[0] eq 'ARRAY' ? @{$self->{$key}}{@{$_[0]}} :
  0         0  
  0         0  
223             $self->{$key}{$_[0]};
224             }
225              
226             # Push on new values and return complete set
227 2 50       9 Carp::croak "Odd number of items in assigment to $name" if(@_ % 2);
228              
229 2         189 while(@_)
230             {
231 4         9 local $_ = shift;
232 4         17 $self->{$key}{$_} = shift;
233             }
234             }
235              
236 4 50       21 return wantarray ? %{$self->{$key}} : $self->{$key};
  0         0  
237             }
238 2         13 }
239             elsif($interface eq 'get_set_all')
240             {
241             $methods{$name} = sub
242             {
243 10     10   1685 my($self) = shift;
244              
245             # If called with no arguments, return hash contents
246 10 100       52 return wantarray ? %{$self->{$key}} : $self->{$key} unless(@_);
  2 100       15  
247              
248             # Set hash to arguments
249 4 100 66     38 if(@_ == 1 && ref $_[0] eq 'HASH')
250             {
251 2         6 $self->{$key} = $_[0];
252             }
253             else
254             {
255             # Push on new values and return complete set
256 2 50       14 Carp::croak "Odd number of items in assigment to $name" if(@_ % 2);
257              
258 2         7 $self->{$key} = {};
259              
260 2         13 while(@_)
261             {
262 4         7 local $_ = shift;
263 4         19 $self->{$key}{$_} = shift;
264             }
265             }
266              
267 4 50       19 return wantarray ? %{$self->{$key}} : $self->{$key};
  0         0  
268             }
269 2         12 }
270             elsif($interface eq 'get_set_init_all')
271             {
272 2   33     11 my $init_method = $args->{'init_method'} || "init_$name";
273              
274             $methods{$name} = sub
275             {
276 16     16   4201 my($self) = shift;
277              
278             # If called with no arguments, return hash contents
279 16 100       43 unless(@_)
280             {
281 12 100       42 $self->{$key} = $self->$init_method() unless(defined $self->{$key});
282 12 100       50 return wantarray ? %{$self->{$key}} : $self->{$key};
  6         45  
283             }
284              
285             # If called with no arguments, return hash contents
286 4 0       13 return wantarray ? %{$self->{$key}} : $self->{$key} unless(@_);
  0 50       0  
287              
288             # Set hash to arguments
289 4 100 66     28 if(@_ == 1 && ref $_[0] eq 'HASH')
290             {
291 2         7 $self->{$key} = $_[0];
292             }
293             else
294             {
295             # Push on new values and return complete set
296 2 50       9 Carp::croak "Odd number of items in assigment to $name" if(@_ % 2);
297              
298 2         6 $self->{$key} = {};
299              
300 2         8 while(@_)
301             {
302 4         6 local $_ = shift;
303 4         17 $self->{$key}{$_} = shift;
304             }
305             }
306              
307 4 50       27 return wantarray ? %{$self->{$key}} : $self->{$key};
  0         0  
308             }
309 2         11 }
310             elsif($interface eq 'clear')
311             {
312             $methods{$name} = sub
313             {
314 4     4   2021 $_[0]->{$key} = {}
315             }
316 6         26 }
317             elsif($interface eq 'reset')
318             {
319             $methods{$name} = sub
320             {
321 2     2   902 $_[0]->{$key} = undef;
322             }
323 6         30 }
324             elsif($interface eq 'delete')
325             {
326             $methods{($interface eq 'manip' ? 'delete_' : '') . $name} = sub
327             {
328 2 50   2   10 Carp::croak "Missing key(s) to delete" unless(@_ > 1);
329              
330 2         5 delete @{shift->{$key}}{@_};
  2         11  
331             }
332 2 50       17 }
333             elsif($interface eq 'exists')
334             {
335             $methods{$name . ($interface eq 'manip' ? '_exists' : '')} = sub
336             {
337 2 50   2   16 Carp::croak "Missing key argument" unless(@_ == 2);
338 2 50       19 defined $_[0]->{$key} ? exists $_[0]->{$key}{$_[1]} : undef;
339             }
340 2 50       18 }
341             elsif($interface =~ /^(?:keys|names)$/)
342             {
343             $methods{$name} = sub
344             {
345 4         34 wantarray ? (defined $_[0]->{$key} ? keys %{$_[0]->{$key}} : ()) :
  0         0  
346 4 50   4   23 (defined $_[0]->{$key} ? [ keys %{$_[0]->{$key}} ] : []);
    0          
    50          
347             }
348 2         13 }
349             elsif($interface eq 'values')
350             {
351             $methods{$name} = sub
352             {
353 4         36 wantarray ? (defined $_[0]->{$key} ? values %{$_[0]->{$key}} : ()) :
  0         0  
354 4 50   4   22 (defined $_[0]->{$key} ? [ values %{$_[0]->{$key}} ] : []);
    0          
    50          
355             }
356 2         12 }
357             elsif($interface eq 'get_set')
358             {
359             $methods{$name} = sub
360             {
361 4     4   11 my($self) = shift;
362              
363             # If called with no arguments, return hash contents
364 4 50       16 unless(@_)
365             {
366 0 0       0 return wantarray ? (defined $self->{$key} ? %{$self->{$key}} : ()) : $self->{$key}
  0 0       0  
367             }
368              
369             # If called with a hash ref, set value
370 4 50 66     28 if(@_ == 1 && ref $_[0] eq 'HASH')
371             {
372 0         0 $self->{$key} = $_[0];
373             }
374             else
375             {
376             # If called with an index, get that value, or a slice for array refs
377 4 100       12 if(@_ == 1)
378             {
379 2 50       17 return ref $_[0] eq 'ARRAY' ? @{$self->{$key}}{@{$_[0]}} :
  0         0  
  0         0  
380             $self->{$key}{$_[0]};
381             }
382              
383             # Push on new values and return complete set
384 2 50       12 Carp::croak "Odd number of items in assigment to $name" if(@_ % 2);
385              
386 2         10 while(@_)
387             {
388 4         7 local $_ = shift;
389 4         18 $self->{$key}{$_} = shift;
390             }
391             }
392              
393 2 50       12 return wantarray ? %{$self->{$key}} : $self->{$key};
  0         0  
394 2         17 };
395             }
396 0         0 else { Carp::croak "Unknown interface: $interface" }
397              
398 30         108 return \%methods;
399             }
400              
401             sub array
402             {
403 18     18 1 28 my($class, $name, $args) = @_;
404              
405 18         20 my %methods;
406              
407 18   66     67 my $key = $args->{'hash_key'} || $name;
408 18   100     1347 my $interface = $args->{'interface'} || 'get_set';
409              
410 18 100       106 if($interface eq 'get_set_init')
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
411             {
412 2   33     11 my $init_method = $args->{'init_method'} || "init_$name";
413              
414             $methods{$name} = sub
415             {
416 12     12   17 my($self) = shift;
417              
418             # If called with no arguments, return array contents
419 12 100       32 unless(@_)
420             {
421 8 100       39 $self->{$key} = $self->$init_method() unless(defined $self->{$key});
422 8 100       35 return wantarray ? @{$self->{$key}} : $self->{$key};
  6         38  
423             }
424              
425             # If called with a array ref, set new value
426 4 100 66     28 if(@_ == 1 && ref $_[0] eq 'ARRAY')
427             {
428 2         6 $self->{$key} = $_[0];
429             }
430             else
431             {
432 2         8 $self->{$key} = [ @_ ];
433             }
434              
435 4 50       18 return wantarray ? @{$self->{$key}} : $self->{$key};
  0         0  
436             }
437 2         13 }
438             elsif($interface eq 'get_set_inited')
439             {
440             $methods{$name} = sub
441             {
442 14     14   1735 my($self) = shift;
443              
444             # If called with no arguments, return array contents
445 14 100       41 unless(@_)
446             {
447 10 100       32 $self->{$key} = [] unless(defined $self->{$key});
448 10 100       38 return wantarray ? @{$self->{$key}} : $self->{$key};
  6         36  
449             }
450              
451             # If called with a array ref, set new value
452 4 100 66     29 if(@_ == 1 && ref $_[0] eq 'ARRAY')
453             {
454 2         5 $self->{$key} = $_[0];
455             }
456             else
457             {
458 2         9 $self->{$key} = [ @_ ];
459             }
460              
461 4 50       22 return wantarray ? @{$self->{$key}} : $self->{$key};
  0         0  
462             }
463 2         10 }
464             elsif($interface eq 'get_set_item')
465             {
466             $methods{$name} = sub
467             {
468 6     6   12 my($self) = shift;
469              
470 6 50       16 Carp::croak "Missing array index" unless(@_);
471              
472 6 100       17 if(@_ == 2)
473             {
474 2         9 return $self->{$key}[$_[0]] = $_[1];
475             }
476             else
477             {
478 4         19 return $self->{$key}[$_[0]]
479             }
480             }
481 2         10 }
482             elsif($interface eq 'unshift')
483             {
484             $methods{$name} = sub
485             {
486 6     6   13 my($self) = shift;
487 6 50       21 Carp::croak "Missing value(s) to add" unless(@_);
488 6 100 100     7 unshift(@{$self->{$key}}, (@_ == 1 && ref $_[0] eq 'ARRAY') ? @{$_[0]} : @_);
  6         53  
  2         10  
489             }
490 2         12 }
491             elsif($interface eq 'shift')
492             {
493             $methods{$name} = sub
494             {
495 4     4   9 my($self) = shift;
496 4 100       17 return splice(@{$self->{$key}}, 0, $_[0]) if(@_);
  2         14  
497 2         4 return shift(@{$self->{$key}})
  2         11  
498             }
499 2         11 }
500             elsif($interface eq 'clear')
501             {
502             $methods{$name} = sub
503             {
504 2     2   24 $_[0]->{$key} = []
505             }
506 2         10 }
507             elsif($interface eq 'reset')
508             {
509             $methods{$name} = sub
510             {
511 0     0   0 $_[0]->{$key} = undef;
512             }
513 0         0 }
514             elsif($interface =~ /^(?:push|add)$/)
515             {
516 2 50       7 if(my $init_method = $args->{'init_method'})
517             {
518             $methods{$name} = sub
519             {
520 0     0   0 my($self) = shift;
521              
522 0 0       0 Carp::croak "Missing value(s) to add" unless(@_);
523              
524 0 0       0 $self->{$key} = $self->$init_method() unless(defined $self->{$key});
525 0 0 0     0 push(@{$self->{$key}}, (@_ == 1 && ref $_[0] && ref $_[0] eq 'ARRAY') ? @{$_[0]} : @_);
  0         0  
  0         0  
526             }
527 0         0 }
528             else
529             {
530             $methods{$name} = sub
531             {
532 6     6   12 my($self) = shift;
533              
534 6 50       18 Carp::croak "Missing value(s) to add" unless(@_);
535              
536 6 100 66     9 push(@{$self->{$key}}, (@_ == 1 && ref $_[0] && ref $_[0] eq 'ARRAY') ? @{$_[0]} : @_);
  6         61  
  2         7  
537             }
538 2         13 }
539             }
540             elsif($interface eq 'pop')
541             {
542             $methods{$name} = sub
543             {
544 6     6   12 my($self) = shift;
545 6 100       20 return splice(@{$self->{$key}}, -$_[0]) if(@_);
  4         35  
546 2         3 return pop(@{$self->{$key}})
  2         13  
547             }
548 2         11 }
549             elsif($interface eq 'get_set')
550             {
551             $methods{$name} = sub
552             {
553 32     32   1524 my($self) = shift;
554              
555             # If called with no arguments, return array contents
556 32 100       86 unless(@_)
557             {
558 26 50       189 return wantarray ? (defined $self->{$key} ? @{$self->{$key}} : ()) : $self->{$key}
  20 100       141  
559             }
560              
561             # If called with a array ref, set new value
562 6 100 66     40 if(@_ == 1 && ref $_[0] eq 'ARRAY')
563             {
564 4         12 $self->{$key} = $_[0];
565             }
566             else
567             {
568 2         8 $self->{$key} = [ @_ ];
569             }
570              
571 6 50       97 return wantarray ? @{$self->{$key}} : $self->{$key};
  0         0  
572             }
573 2         16 }
574 0         0 else { Carp::croak "Unknown interface: $interface" }
575              
576 18         60 return \%methods;
577             }
578              
579             1;
580              
581             __END__