File Coverage

blib/lib/Class/Property.pm
Criterion Covered Total %
statement 40 48 83.3
branch 2 2 100.0
condition n/a
subroutine 17 21 80.9
pod 0 4 0.0
total 59 75 78.6


line stmt bran cond sub pod time code
1             package Class::Property;
2 1     1   18222 use strict; use warnings FATAL => 'all';
  1     1   1  
  1         37  
  1         4  
  1         1  
  1         45  
3 1     1   433 use parent 'Exporter';
  1         248  
  1         4  
4 1     1   52 use 5.010;
  1         3  
  1         26  
5 1     1   3 use Carp;
  1         1  
  1         960  
6            
7             our $VERSION = 'v1.0.0';
8            
9             our @EXPORT;
10            
11             my $GEN = {
12             'default' => sub
13             {
14             my( $prop_name ) = @_;
15            
16             return sub: lvalue
17             {
18 9     9   119 return shift->{$prop_name};
19             };
20             },
21             'default_lazy' => sub
22             {
23             my( $prop_name, $lazy_init ) = @_;
24             my $lazy_called = 0;
25             require Class::Property::RW::Lazy;
26            
27             return sub: lvalue
28             {
29 8 100   8   591 if( $lazy_called )
30             {
31 5         18 return shift->{$prop_name};
32             }
33             else
34             {
35 3         22 tie my $val, 'Class::Property::RW::Lazy', shift, $prop_name, $lazy_init, \$lazy_called;
36 3         17 return $val;
37             }
38             };
39             },
40             'lazy_get_default_set' => sub
41             {
42             my( $prop_name, $lazy_init, $setter ) = @_;
43             my $lazy_called = 0;
44             require Class::Property::RW::Lazy::CustomSet;
45            
46             return sub: lvalue
47             {
48 0     0   0 tie my $val, 'Class::Property::RW::Lazy::CustomSet', shift, $prop_name, $lazy_init, $setter, \$lazy_called;
49 0         0 return $val;
50             };
51             },
52             'custom' => sub
53             {
54             my( $getter, $setter ) = @_;
55             require Class::Property::RW::Custom;
56            
57             return sub: lvalue
58             {
59 2     2   14 tie my $val, 'Class::Property::RW::Custom', shift, $getter, $setter;
60 2         11 return $val;
61             };
62             },
63             'default_get_custom_set' => sub
64             {
65             my( $prop_name, $setter ) = @_;
66             require Class::Property::RW::CustomSet;
67            
68             return sub: lvalue
69             {
70 0     0   0 tie my $val, 'Class::Property::RW::CustomSet', shift, $prop_name, $setter;
71 0         0 return $val;
72             };
73             },
74             'custom_get_default_set' => sub
75             {
76             my( $prop_name, $getter ) = @_;
77             require Class::Property::RW::CustomGet;
78            
79             return sub: lvalue
80             {
81 3     3   20 tie my $val, 'Class::Property::RW::CustomGet', shift, $prop_name, $getter;
82 3         23 return $val;
83             };
84             },
85             'default_ro' => sub
86             {
87             my( $prop_name ) = @_;
88             require Class::Property::RO;
89            
90             return sub: lvalue
91             {
92 7     7   68 tie my $val, 'Class::Property::RO', shift, $prop_name;
93 7         41 return $val;
94             };
95             },
96             'custom_ro' => sub
97             {
98             my( $prop_name, $getter ) = @_;
99             require Class::Property::RO::CustomGet;
100            
101             return sub: lvalue
102             {
103 0     0   0 tie my $val, 'Class::Property::RO::CustomGet', shift, $prop_name, $getter;
104 0         0 return $val;
105             };
106             },
107             'lazy_ro' => sub
108             {
109             my( $prop_name, $lazy_init ) = @_;
110             my $lazy_called = 0;
111             require Class::Property::RO::Lazy;
112            
113             return sub: lvalue
114             {
115 3     3   34 tie my $val, 'Class::Property::RO::Lazy', shift, $prop_name, $lazy_init, \$lazy_called;
116 3         22 return $val;
117             };
118             },
119             'default_wo' => sub: lvalue
120             {
121             my( $prop_name ) = @_;
122             require Class::Property::WO;
123            
124             return sub: lvalue
125             {
126 5     5   42 tie my $val, 'Class::Property::WO', shift, $prop_name;
127 5         34 return $val;
128             };
129             },
130             'custom_wo' => sub: lvalue
131             {
132             my( $prop_name, $setter ) = @_;
133             require Class::Property::WO::CustomSet;
134            
135             return sub: lvalue
136             {
137 0     0   0 tie my $val, 'Class::Property::WO::CustomSet', shift, $prop_name, $setter;
138 0         0 return $val;
139             };
140             },
141             };
142            
143             # creating new property by names
144             # input is a hash of
145             # property_name => hashref
146             # and hashref is:
147             #
148             # get => CODEREF | anything # creates getter custom or default
149             # get_lazy => CODEREF # creates default getter with lazy init method from CODEREF
150             # set => CODREF | anything # creates custom or default setter
151             #
152             my $make_property = sub
153             {
154             my( $package, %kwargs ) = @_;
155            
156             #use Data::Dumper; warn "Invoked $package with ".Dumper(\%kwargs);
157            
158             foreach my $prop_name (keys(%kwargs))
159             {
160             my $prop_settings = $kwargs{$prop_name};
161             my $prop_methodname = "${package}::$prop_name";
162             my $prop_method;
163            
164             if( # regular property
165             exists $prop_settings->{'get'}
166             and exists $prop_settings->{'set'}
167             )
168             {
169             my( $get_type, $set_type ) = ( ref $prop_settings->{'get'}, ref $prop_settings->{'set'} );
170            
171             if( $get_type eq 'CODE' and $set_type eq 'CODE' ) # custom setter and gettter
172             {
173             $prop_method = $GEN->{'custom'}->(@{$prop_settings}{'get', 'set'});
174             }
175             elsif( $get_type eq 'CODE' ) # custom getter and default setter
176             {
177             $prop_method = $GEN->{'custom_get_default_set'}->($prop_name, @{$prop_settings}{'get'});
178             }
179             elsif( $set_type eq 'CODE' ) # default getter and custom setter
180             {
181             $prop_method = $GEN->{'default_get_custom_set'}->($prop_name, @{$prop_settings}{'set'});
182             }
183             else # default getter and setter
184             {
185             $prop_method = $GEN->{'default'}->($prop_name);
186             }
187             }
188             elsif( # regular property with lazy init
189             exists $prop_settings->{'get_lazy'}
190             and exists $prop_settings->{'set'}
191             )
192             {
193             croak 'get_lazy parameter should be a coderef' if ref $prop_settings->{'get_lazy'} ne 'CODE';
194             my $set_type = ref $prop_settings->{'set'};
195             if( $set_type eq 'CODE' )
196             {
197             $prop_method = $GEN->{'lazy_get_default_set'}->($prop_name, $prop_settings->{'get_lazy'}, $prop_settings->{'set'});
198             }
199             else
200             {
201             $prop_method = $GEN->{'default_lazy'}->($prop_name, $prop_settings->{'get_lazy'});
202             }
203             }
204             elsif( exists $prop_settings->{'get'} ) # ro property
205             {
206             if( ref $prop_settings->{'get'} eq 'CODE' ) # RO custom getter
207             {
208             $prop_method = $GEN->{'custom_ro'}->($prop_name, $prop_settings->{'get'});
209             }
210             else
211             {
212             $prop_method = $GEN->{'default_ro'}->($prop_name);
213             }
214             }
215             elsif( exists $prop_settings->{'get_lazy'} ) # ro property with lazy init
216             {
217             croak 'get_lazy parameter should be a coderef' if ref $prop_settings->{'get_lazy'} ne 'CODE';
218             $prop_method = $GEN->{'lazy_ro'}->($prop_name, $prop_settings->{'get_lazy'});
219             }
220             elsif( exists $prop_settings->{'set'} ) # wo property
221             {
222             if( ref $prop_settings->{'set'} eq 'CODE' ) # WO custom setter
223             {
224             $prop_method = $GEN->{'custom_wo'}->($prop_name, $prop_settings->{'set'});
225             }
226             else
227             {
228             $prop_method = $GEN->{'default_wo'}->($prop_name);
229             }
230             }
231            
232             if(defined $prop_method)
233             {
234 1     1   6 no strict 'refs';
  1         2  
  1         219  
235             *{$prop_methodname} = $prop_method;
236             }
237             }
238            
239             return $package;
240             };
241            
242             push @EXPORT, 'property';
243 2     2 0 32379 sub property{ return $make_property->( (caller)[0], @_);}
244             push @EXPORT, 'rw_property';
245 1     1 0 16 sub rw_property{ return $make_property->( (caller)[0], map{$_ => {'set' => undef, 'get' => undef }} @_);}
  2         14  
246             push @EXPORT, 'ro_property';
247 1     1 0 10 sub ro_property{ return $make_property->( (caller)[0], map{$_ => {'get' => undef }} @_);}
  1         7  
248             push @EXPORT, 'wo_property';
249 1     1 0 9 sub wo_property{ return $make_property->( (caller)[0], map{$_ => {'set' => undef }} @_);}
  1         6  
250            
251             __END__