File Coverage

blib/lib/Class/props.pm
Criterion Covered Total %
statement 71 80 88.7
branch 40 50 80.0
condition 19 29 65.5
subroutine 14 14 100.0
pod 1 1 100.0
total 145 174 83.3


line stmt bran cond sub pod time code
1             package Class::props ;
2             $VERSION = 2.30 ;
3 9     9   767 use 5.006_001 ;
  9         34  
  9         363  
4 9     9   46 use strict ;
  9         23  
  9         309  
5            
6             # This file uses the "Perlish" coding style
7             # please read http://perl.4pro.net/perlish_coding_style.html
8              
9             ; use Carp
10 9     9   54 ; $Carp::Internal{+__PACKAGE__}++
  9         16  
  9         3432  
11              
12             ; sub import
13 15     15   222 { my $tool = shift
14 15         68 ; $tool->add_to(scalar caller, @_)
15             }
16              
17             ; sub add_to
18 15     15 1 45 { my ($tool, $pkg, @args) = @_
19 15         374 ; foreach my $prop ( @args )
20 43         109 { $prop = $tool->_init_prop_param( $prop )
21 43         209 ; $tool->_add_prop( $pkg, $prop )
22             }
23             }
24              
25             ; sub _init_prop_param
26 54     54   80 { my ( $tool, $prop ) = @_
27 54 100       165 ; $prop = { name => $prop }
28             unless ref $prop eq 'HASH'
29 54 100       204 ; $$prop{name} = [ $$prop{name} ]
30             unless ref $$prop{name} eq 'ARRAY'
31 54 50 50     221 ; $$prop{allowed} &&= [ $$prop{allowed} ]
32             unless ref $$prop{allowed} eq 'ARRAY'
33 54         110 ; $prop
34             }
35            
36             ; sub _add_prop
37 54     54   92 { my ( $tool, $pkg, $prop ) = @_
38 54         96 ; my $gr = delete $$prop{group}
39 54   66     469 ; my $to_tie = ( defined $$prop{default}
40             || defined $$prop{protected}
41             || defined $$prop{allowed}
42             || defined $$prop{validation}
43             || defined $$prop{post_process}
44             )
45 54         65 ; foreach my $n ( @{$$prop{name}} ) # foreach property
  54         117  
46 9         4018 { no strict 'refs'
47 9     9   52 ; *{$pkg.'::'.$n}
  9         24  
  64         4351  
48             = sub : lvalue
49 235 50   235   11507 { (@_ > 2) && croak qq(Too many arguments for "$n" property, died)
50 22   66     119 ; my $scalar
51             = $tool =~ /^Class/ ? $gr
52 52   66     252 ? \${(ref $_[0]||$_[0]).'::'.$gr}{$n}
53 15         75 : \${(ref $_[0]||$_[0]).'::'.$n}
54             : $tool =~ /^Package/ ? $gr
55 62         197 ? \${$pkg.'::'.$gr}{$n}
56 235 100       1059 : \${$pkg.'::'.$n}
    100          
    100          
    100          
    100          
57             : $gr
58             ? \$_[0]{$gr}{$n}
59             : \$_[0]{$n}
60 235         308 ; my $Tscalar
61 235 100       447 ; if ( $to_tie )
62 168         805 { tie $$Tscalar
63             , 'Class::props::Tie'
64             , $_[0] # [0] object/class
65             , $n # [1] prop name
66             , $scalar # [2] lvalue ref
67             , $prop # [3] options ref
68             }
69             else
70 67         86 { $Tscalar = $scalar
71             }
72 235 100       1167 ; @_ == 2
73             ? ( $$Tscalar = $_[1] )
74             : $$Tscalar
75             }
76 64         283 }
77             }
78              
79             ; package Class::props::Tie
80             ; use Carp
81 9     9   58 ; $Carp::Internal{+__PACKAGE__}++
  9         15  
  9         724  
82             ; use strict
83              
84 9     9   46 ; sub TIESCALAR
  9         12  
  9         6379  
85 168     168   673 { bless \@_, shift
86             }
87            
88             ; sub FETCH
89             { my $val = do
90 102 100   102   965 { if ( defined ${$_[0][2]} )
  102 50       118  
  102         385  
91 58         65 { ${$_[0][2]}
  58         118  
92             }
93             elsif ( defined $_[0][3]{default} )
94 44 100       171 { my $def = ref $_[0][3]{default} eq 'CODE'
95             ? $_[0][3]{default}( $_[0][0] )
96             : $_[0][3]{default}
97 0         0 ; $_[0][3]{no_strict}
98 44 50       191 ? ${$_[0][2]} = $def
99             : $_[0]->STORE( $def )
100             }
101             else
102             { undef
103 0         0 }
104             }
105 102         160 ; local $_ = $val
106 102 100       510 ; defined $_[0][3]{post_process}
107             ? $_[0][3]{post_process}( $_[0][0], $val )
108             : $val
109             }
110              
111             ; sub STORE
112 128   100 128   1521 { my $from_FETCH = (caller(1))[3]
113             && (caller(1))[3] =~ /::FETCH$/
114 128 100       374 ; my $default = $from_FETCH
115             ? 'default '
116             : ''
117 128 100 100     500 ; if ( $_[0][3]{protected} # if protected
      66        
118             &&! $from_FETCH # bypass for default
119             &&! $Class::props::force # bypass deliberately
120             )
121 18         23 { my ($OK, $f)
122 18         40 ; until ( $OK )
123 36 100       100 { last unless my $caller = caller($f++)
124 30         179 ; $OK = $caller->can($_[0][1])
125             }
126 18 100       884 ; $OK || croak qq("$_[0][1]" is a read-only property, died)
127             }
128 122 0 33     343 ; if ( $_[0][3]{allowed} # if restricted
      33        
129             &&! $from_FETCH # bypass for default
130             &&! $Class::props::force # bypass deliberately
131             )
132 0         0 { my ($OK, $f)
133 0         0 ; until ( $OK )
134 0 0       0 { last unless my $caller = (caller($f++))[3]
135 0         0 ; $OK = grep { $caller =~ qr/$_/ } @{$_[0][3]{allowed}}
  0         0  
  0         0  
136             }
137 0 0       0 ; $OK || croak qq("$_[0][1]" is a read-only property, died)
138             }
139 122         194 ; local $_ = $_[1]
140 122 100 66     434 ; if ( defined $_[0][3]{validation} # validation subref
141             && defined $_ # bypass for undef (reset to default)
142             )
143 41 100       162 { $_[0][3]{validation}( $_[0][0], $_)
144             || croak qq(Invalid ${default}value for "$_[0][1]" property, died)
145             }
146 116         288 ; ${$_[0][2]} = $_
  116         508  
147             }
148              
149             1 ;
150              
151             __END__