File Coverage

blib/lib/Object/AutoAccessor.pm
Criterion Covered Total %
statement 131 158 82.9
branch 50 76 65.7
condition 7 15 46.6
subroutine 20 22 90.9
pod 9 15 60.0
total 217 286 75.8


line stmt bran cond sub pod time code
1             package Object::AutoAccessor;
2              
3             require 5.004;
4 5     5   127830 use strict;
  5         14  
  5         213  
5 5     5   34 use Carp; # require 5.004
  5         7  
  5         557  
6              
7 5     5   32 use vars qw($VERSION $AUTOLOAD);
  5         20  
  5         12180  
8              
9             $VERSION = '0.06';
10              
11             sub new {
12 19     19 1 3591 my $obj = shift;
13 19   33     87 my $class = ref($obj) || $obj;
14            
15 19 50       55 unless (@_ % 2 == 0) {
16 0         0 croak "Odd number of argumentes for $class->new()";
17             }
18            
19 19         34 my %args = @_;
20 19         47 my $options = { autoload => 1 };
21 19         66 $options->{$_} = $args{$_} for keys %args;
22 19         93 bless $options, $class;
23             }
24              
25             sub renew {
26 7     7 1 10 my $obj = shift;
27 7   33     22 my $class = ref($obj) || $obj;
28            
29 7 50       21 unless (@_ % 2 == 0) {
30 0         0 croak "Odd number of argumentes for $class->renew()";
31             }
32            
33 7         21 my %args = @_;
34 7 50 33     47 if (ref($obj) and UNIVERSAL::isa($obj, __PACKAGE__)) {
35 7         40 %args = map { $_ => $obj->{$_} } grep !/^params$/, keys %$obj;
  7         25  
36             }
37 7         24 $class->new(%args);
38             }
39              
40 0     0 0 0 sub renew_node { shift->renew(@_) }
41              
42             sub new_node {
43 5     5 1 11 my $self = shift;
44            
45 5 50       14 unless (@_) {
46 0         0 croak "Not enough arguments for " . ref($self) . "->new_node()";
47             }
48            
49 5         7 my $label = shift;
50 5         586 my $child = $self->renew(@_);
51 5         13 $self->param($label => $child);
52 5         21 $child;
53             }
54              
55             sub node {
56 9     9 1 13 my $self = shift;
57            
58 9 100       22 unless (@_) {
59 7         8 return grep { $self->is_node($_) } keys(%{ $self->{params} });
  9         15  
  7         23  
60             }
61            
62 2         2 my $first = shift;
63            
64 2 50       5 if (@_) {
65 0         0 my @children = ();
66 0         0 for my $label ($first,@_) {
67 0 0       0 if ($self->is_node($label)) {
68 0         0 push(@children, $self->{params}->{$label});
69             }
70             else {
71 0         0 push(@children, undef);
72             }
73             }
74 0 0       0 return wantarray ? @children : [@children];
75             }
76             else {
77 2 50       4 if ($self->is_node($first)) {
78 2         11 return $self->{params}->{$first};
79             }
80             else {
81 0         0 return undef;
82             }
83             }
84             }
85              
86 6     6 1 15 sub has_node { scalar shift->node() }
87              
88             sub is_node {
89 86     86 0 128 my $self = shift;
90            
91 86 50       161 unless (@_) {
92 0         0 croak "Not enough arguments for " . ref($self) . "->is_node()";
93             }
94            
95 86         104 my $label = shift;
96 86   100     1141 return (ref($self->{params}->{$label}) and UNIVERSAL::isa($self->{params}->{$label}, __PACKAGE__));
97             }
98              
99             sub param {
100 49     49 1 71 my $self = shift;
101            
102 49 100       117 unless (@_) {
103 4         5 return grep { !$self->is_node($_) } keys(%{ $self->{params} });
  14         40  
  4         14  
104             }
105            
106 45         51 my $first = shift;
107            
108 45 100       77 if (@_) {
109 28 50       64 croak "Odd number of argumentes for " . ref($self) . "->param()" unless ((@_ % 2) == 1);
110            
111 28         144 my %hash = ($first,@_);
112            
113 28         64 for my $key (keys %hash) {
114 29         42 my $ref = ( ref $hash{$key} );
115            
116 29 100       95 if ($ref eq 'HASH') {
    100          
    50          
117 1         2 %{ $self->{params}->{$key} } = %{ $hash{$key} };
  1         5  
  1         3  
118             }
119             elsif ($ref eq 'ARRAY') {
120 1         2 @{ $self->{params}->{$key} } = @{ $hash{$key} };
  1         5  
  1         2  
121             }
122             elsif ($ref eq 'SCALAR') {
123 0         0 $self->{params}->{$key} = $hash{$key};
124             }
125             else {
126 27         95 $self->{params}->{$key} = $hash{$key};
127             }
128             }
129            
130 28 100       75 if (@_ == 1) {
131 27         92 return $self->{params}->{$first};
132             }
133             }
134             else {
135 17 100       41 if ($self->is_node($first)) {
136 1         4 return undef;
137             }
138            
139 16         31 my $type = ( ref $self->{params}->{$first} );
140            
141 16 50       66 if ($type eq 'HASH') {
    50          
    50          
142 0         0 return \%{ $self->{params}->{$first} };
  0         0  
143             }
144             elsif ($type eq 'ARRAY') {
145 0         0 return \@{ $self->{params}->{$first} };
  0         0  
146             }
147             elsif ($type eq 'SCALAR') {
148 0         0 return $self->{params}->{$first};
149             }
150             else { # CODEREF, IO, GLOB, OBJECT
151 16         84 return $self->{params}->{$first};
152             }
153             }
154             }
155              
156             sub defined {
157 9     9 0 165 my $self = shift;
158            
159 9 50       91 unless (@_) {
160 0         0 croak "Not enough arguments for " . ref($self) . "->defined()";
161             }
162            
163 9         10 my $label = shift;
164 9         40 return CORE::defined($self->{params}->{$label});
165             }
166              
167             sub exists {
168 3     3 0 5 my $self = shift;
169            
170 3 50       10 unless (@_) {
171 0         0 croak "Not enough arguments for " . ref($self) . "->exists()";
172             }
173            
174 3         4 my $label = shift;
175 3         16 return CORE::exists($self->{params}->{$label});
176             }
177              
178             sub delete {
179 1     1 0 2 my $self = shift;
180            
181 1 50       3 unless (@_) {
182 0         0 croak "Not enough arguments for " . ref($self) . "->delete()";
183             }
184            
185 1         2 my $label = shift;
186 1         5 return CORE::delete($self->{params}->{$label});
187             }
188              
189             sub undef {
190 1     1 0 2 my $self = shift;
191            
192 1 50       7 unless (@_) {
193 0         0 croak "Not enough arguments for " . ref($self) . "->undef()";
194             }
195            
196 1         3 my $label = shift;
197 1         3 return CORE::undef($self->{params}->{$label});
198             }
199              
200             sub build {
201 1     1 1 19 my $obj = shift;
202 1   33     6 my $class = ref($obj) || $obj;
203            
204 1 50       4 unless (@_) {
205 0         0 croak "Not enough arguments for " . $class . "->build()";
206             }
207            
208 1         2 my $hashref = shift;
209            
210 1 50       6 unless (UNIVERSAL::isa($hashref, 'HASH')) {
211 0         0 croak $class . "->build(): Cannot build: argument is not a HASH reference";
212             }
213            
214 1         5 my $self = $class->new(@_);
215            
216 1         4 $self->_build($hashref);
217            
218 1         21 $self;
219             }
220              
221             sub _build {
222 3     3   5 my $self = shift;
223 3         3 my $struct = shift;
224            
225 3         8 for my $key (keys %$struct) {
226 5 100       17 if (UNIVERSAL::isa($struct->{$key}, 'HASH')) {
227 2         5 $self->new_node($key)->_build($struct->{$key});
228             }
229             else {
230 3         7 $self->param( $key => $struct->{$key} );
231             }
232             }
233             }
234              
235             sub as_hashref {
236 1     1 1 2 my $self = shift;
237            
238 1         2 my $hashref = {};
239            
240 1         3 $self->_as_hashref($hashref);
241             }
242              
243             sub _as_hashref {
244 3     3   4 my $self = shift;
245 3         5 my $hashref = shift;
246            
247 3         3 for my $key (keys %{ $self->{params} }) {
  3         7  
248 5 100       17 if (UNIVERSAL::isa($self->{params}->{$key}, __PACKAGE__)) {
249 2         4 $hashref->{$key} = $self->node($key)->_as_hashref($hashref->{$key});
250             }
251             else {
252 3         6 $hashref->{$key} = $self->param($key);
253             }
254             }
255            
256 3         12 $hashref;
257             }
258              
259             sub autoload {
260 4     4 1 6 my $self = shift;
261 4 50       11 $self->{autoload} = shift if @_;
262 4         11 $self->{autoload};
263             }
264              
265             sub AUTOLOAD {
266 45     45   875 my $self = shift;
267            
268 45 50       207 return if $AUTOLOAD =~ /::DESTROY$/;
269            
270 45         231 my ($method) = ($AUTOLOAD =~ /.*::(.*?)$/);
271            
272 45 100       117 if ( $self->{autoload} ) {
273 41 50       191 if ( $self->can( $method ) ) {
    100          
274 0         0 return $self->$method( @_ );
275             }
276             elsif ($method =~ /^([sg]et_)(.*)$/) {
277 2         6 my($prefix, $name) = ($1, $2);
278 2 100       4 if ($prefix eq 'set_') {
279 1         4 return $self->param($name => @_);
280             }
281             else {
282 1 50       4 carp "Too many arguments for " . ref($self) . "->get_$name\()" if @_;
283 1         3 return $self->param($name);
284             }
285             }
286             else {
287 39 100       84 if ($self->is_node($method)) {
288 15 100       38 if (@_) {
289 1         4 undef $self->{params}->{$method};
290 1         5 return $self->param($method => @_);
291             }
292             else {
293 14         83 return $self->{params}->{$method};
294             }
295             }
296             else {
297 24         66 return $self->param($method => @_);
298             }
299             }
300             }
301             else {
302 4         412 croak(ref($self) . "->$method\() : this method is not implimented");
303             }
304            
305 0           return;
306             }
307              
308 0     0     sub DESTROY {}
309              
310             1;
311             __END__