File Coverage

blib/lib/Class/Member/HASH.pm
Criterion Covered Total %
statement 71 77 92.2
branch 18 22 81.8
condition 2 3 66.6
subroutine 13 14 92.8
pod n/a
total 104 116 89.6


line stmt bran cond sub pod time code
1             package Class::Member::HASH;
2              
3 2     2   59701 use strict;
  2         5  
  2         108  
4             our $VERSION='1.6';
5              
6 2     2   12 use Carp 'confess';
  2         3  
  2         204  
7              
8             my $get_class_members;
9             $get_class_members=sub {
10             my $pack=$_[0];
11 2     2   12 no strict 'refs';
  2         9  
  2         982  
12             my %cm;
13             @cm{@{$pack.'::CLASS_MEMBERS'}}=();
14             foreach my $p (@{$pack.'::ISA'}) {
15             @cm{$get_class_members->($p)}=();
16             }
17             return keys %cm;
18             };
19              
20             sub import {
21 3     3   19 my $pack=shift;
22 3         8 ($pack)=caller;
23              
24             my $getset=sub : lvalue {
25 26     26   31 my $I=shift;
26 26         32 my $what=shift;
27 26 100       82 unless( UNIVERSAL::isa( $I, 'HASH' ) ) {
28 1         370 confess "$pack\::$what must be called as instance method\n";
29             }
30 25         48 $what=$pack.'::'.$what;
31 25 100       57 if( $#_>=0 ) {
32 2         5 $I->{$what}=shift;
33             }
34 25         1034 $I->{$what};
35 3         11 };
36              
37             my $new=sub {
38 2     2   20 my $parent=shift;
39 2   66     11 my $class=ref($parent) || $parent;
40              
41 2         7 my $I=bless {}=>$class;
42 2         8 my %o=@_;
43 2         8 my @CLASS_MEMBERS=$get_class_members->($pack);
44              
45 2 100       10 if( ref($parent) ) { # inherit first
46 1         2 foreach my $m (@CLASS_MEMBERS) {
47 3         11 $I->$m=$parent->$m;
48             }
49             }
50              
51             # then override with named parameters
52 2         5 foreach my $m (@CLASS_MEMBERS) {
53 6 100       23 $I->$m=$o{$m} if( exists $o{$m} );
54             }
55              
56 2         17 my $init=$I->can('I N I T');
57 2 50       7 if( $init ) {
58 2         7 $init=$init->();
59 2         15 $I->$init;
60             }
61              
62 2         9 return $I;
63 3         14 };
64              
65 3         7 foreach my $name (@_) {
66 10 100       32 if( $name=~/^-(.*)/ ) { # reserved name, aka option
67 5         17 my $o=$1;
68 5 100       21 if( $o eq 'CLASS_MEMBERS' ) {
    100          
    50          
    50          
    50          
69 3         3 local $_;
70 2     2   11 no strict 'refs';
  2         4  
  2         164  
71 3         6 *{$pack.'::CLASS_MEMBERS'}=[grep {!/^-/} @_];
  3         1918  
  10         26  
72             } elsif( $o=~/^NEW=(.+)/ ) {
73 2     2   8 no strict 'refs';
  2         3  
  2         78  
74 1         8 *{$pack.'::'.$1}=$new;
  1         34  
75             } elsif( $o eq 'NEW' ) {
76 2     2   8 no strict 'refs';
  2         5  
  2         100  
77 0         0 *{$pack.'::new'}=$new;
  0         0  
78             } elsif( $o=~/^INIT=(.+)/ ) {
79 2     2   9 no strict 'refs';
  2         4  
  2         137  
80 0         0 my $init="$1";
81 0     0   0 *{$pack.'::I N I T'}=sub(){$init};
  0         0  
  0         0  
82             } elsif( $o eq 'INIT' ) {
83 2     2   9 no strict 'refs';
  2         2  
  2         115  
84 1         2 *{$pack.'::I N I T'}=sub(){"init"};
  1         40  
85             }
86             } else {
87 2     2   13 no strict 'refs';
  2         9  
  2         212  
88 5         28 *{$pack.'::'.$name}=sub:lvalue {
89 26     26   705 my $I=shift;
90 26         33 &{$getset}( $I, $name, @_ );
  26         57  
91 5         13 };
92             }
93             }
94             }
95              
96             1;
97              
98             __END__