File Coverage

blib/lib/Class/Accessor/Array.pm
Criterion Covered Total %
statement 70 72 97.2
branch 16 28 57.1
condition 2 2 100.0
subroutine 3 3 100.0
pod n/a
total 91 105 86.6


line stmt bran cond sub pod time code
1             package Class::Accessor::Array;
2              
3             our $DATE = '2017-08-27'; # DATE
4             our $VERSION = '0.031'; # VERSION
5              
6             #IFUNBUILT
7             # use strict 'subs', 'vars';
8             # use warnings;
9             #END IFUNBUILT
10              
11             sub import {
12 3     3   683 my ($class0, $spec) = @_;
13 3         11 my $caller = caller();
14              
15 3         58 my $class = $caller;
16              
17             #IFUNBUILT
18             # no warnings 'redefine';
19             #END IFUNBUILT
20              
21             # generate accessors
22 3         6 for my $meth (keys %{$spec->{accessors}}) {
  3         12  
23 5         12 my $idx = $spec->{accessors}{$meth};
24 5         7 my $code_str = 'sub (;$) { ';
25 5         12 $code_str .= "\$_[0][$idx] = \$_[1] if \@_ > 1; ";
26 5         9 $code_str .= "\$_[0][$idx]; ";
27 5         9 $code_str .= "}";
28             #say "D:accessor code for $meth: ", $code_str;
29 5 50   2   383 *{"$class\::$meth"} = eval $code_str;
  5 50       22  
  2 50       21  
  2 50       19  
  4 50       46  
  4         35  
  1         34  
  1         3  
  4         55  
  4         36  
  1         22  
  1         2  
30 5 50       43 die if $@;
31             }
32              
33             # generate constructor
34             {
35 3         5 my $code_str;
  3         3  
36 3         6 $code_str = 'sub { my ($class, %args) = @_;';
37 3 100       4 if (@{"$class\::ISA"}) {
  3         13  
38 1         2 $code_str .= ' require '.${"$class\::ISA"}[0].';';
  1         5  
39 1         4 $code_str .= ' my $self = '.${"$class\::ISA"}[0].'->new(map {($_=>delete $args{$_})}'.
40 1         1 ' grep {'.(join " && ", map {'$_ ne \''.$_.'\''} keys %{$spec->{accessors}}).'} keys %args);';
  1         4  
  1         3  
41 1         2 $code_str .= ' $self = bless $self, \''.$class.'\';';
42             } else {
43 2         4 $code_str .= ' my $self = bless [], $class;';
44             }
45 3         5 $code_str .= ' for my $key (grep {'.(join " || ", map {'$_ eq \''.$_.'\''} keys %{$spec->{accessors}}).'} keys %args) { $self->$key(delete $args{$key}) }';
  5         15  
  3         7  
46 3         11 $code_str .= ' die "Unknown $class attributes in constructor: ".join(", ", sort keys %args) if keys %args;';
47 3         5 $code_str .= ' $self }';
48              
49             #print "D:constructor code for class $class: ", $code_str, "\n";
50 3   100     12 my $constructor = $spec->{constructor} || "new";
51 3 50       4 unless (*{"$class\::$constructor"}{CODE}) {
  3         15  
52 3 0   1   432 *{"$class\::$constructor"} = eval $code_str;
  3 50       12  
  1 100       720  
  1 100       3  
  1 50       4  
  0         0  
  0         0  
  1         4  
  1         2  
  6         1888  
  6         13  
  6         17  
  6         27  
  4         67  
  6         39  
  4         38  
  3         3932  
  3         14  
  3         28  
  3         38  
  4         8  
  2         5  
  2         5  
  1         3  
  1         17  
  2         6  
  2         5  
53 3 50       57 die if $@;
54             };
55             }
56             }
57              
58             1;
59             # ABSTRACT: Generate accessors/constructor for array-based object
60              
61             __END__