File Coverage

blib/lib/Eixo/Base/Clase.pm
Criterion Covered Total %
statement 101 133 75.9
branch 13 26 50.0
condition 3 6 50.0
subroutine 25 30 83.3
pod 0 8 0.0
total 142 203 69.9


line stmt bran cond sub pod time code
1             package Eixo::Base::Clase;
2              
3 9     9   46919 use Eixo::Base::Util;
  9         13  
  9         225  
4 9     9   3190 use Clone 'clone';
  9         16093  
  9         418  
5              
6 9     9   72 use Attribute::Handlers;
  9         10  
  9         34  
7 9     9   152 use strict;
  9         8  
  9         117  
8 9     9   24 use warnings;
  9         6  
  9         839  
9              
10              
11             sub import{
12 21     21   57538 my $class = shift;
13              
14 21         331 $_->import for qw(strict warnings utf8);
15              
16 21 100       81 return unless($class eq 'Eixo::Base::Clase');
17              
18 18 100 100     72 if(@_ && $_[0] eq '-norequire'){
19 3         5 shift @_;
20             }
21             else{
22 15         30 foreach my $f (my @copy = @_){
23              
24 6         48 $f =~ s!::|'!/!g;
25              
26 9     9   36 no strict 'refs';
  9         11  
  9         468  
27              
28 6         1358 require "$f.pm";
29              
30             }
31             }
32              
33 18 100       54 my @inheritance = (@_ > 0) ? @_ : $class;
34              
35 18         23 my $caller = caller;
36              
37             {
38 9     9   32 no strict 'refs';
  9         7  
  9         956  
  18         19  
39              
40 18         19 foreach my $my_class (@inheritance){
41              
42              
43 19 50       698 next if($caller->isa($my_class));
44              
45             #print "------>$caller $my_class \n";
46              
47 19         590 push @{"${caller}\:\:ISA"}, $my_class;
  19         181  
48              
49              
50             }
51              
52              
53 18         27 *{$caller . '::has'} = \&has;
  18         1250  
54              
55             };
56              
57              
58             }
59              
60              
61              
62             sub has{
63 11     11 0 103 my (%attributes) = @_;
64              
65 11         90 my $class = (caller(0))[0];
66              
67 9     9   31 no strict 'refs';
  9         11  
  9         996  
68            
69 11         34 foreach my $attribute (keys(%attributes)){
70              
71 34         135 $class->__createSetterGetter($attribute, $attributes{$attribute});
72             }
73              
74 11         47 *{$class . '::' . '__initialize'} = sub {
75              
76 22     22   145 my $c_attributes = clone(\%attributes);
77              
78 22         24 my ($self) = @_;
79              
80 22         42 foreach(keys %$c_attributes){
81              
82 56         106 $self->{$_} = $c_attributes->{$_};
83             }
84 11         33 };
85             }
86              
87             sub __createSetterGetter{
88 17     17   19 my ($class, $attribute, $value) = @_;
89              
90 9     9   33 no strict 'refs';
  9         16  
  9         1074  
91              
92 17 50       14 unless(defined(&{$class . '::' . $attribute})){
  17         54  
93              
94 17         45 *{$class . '::' . $attribute} = sub {
95              
96 5     5   909 my ($self, $value) = @_;
97              
98 5 50       10 if(defined($value)){
99            
100 0         0 $self->{$attribute} = $value;
101            
102 0         0 $self;
103             }
104             else{
105 5         15 $self->{$attribute};
106             }
107              
108 17         33 };
109             }
110              
111             }
112              
113             sub new{
114 4     4 0 839 my ($clase, @args) = @_;
115              
116 4         8 my $self = bless({}, $clase);
117              
118             # initialize attributes with default values from 'has'
119 4         19 $self->__chainInitialize;
120              
121             # finally call initialize method
122 4         15 $self->initialize(@args);
123              
124 4         7 $self;
125             }
126              
127              
128             sub __chainInitialize{
129 12     12   15 my ($self) = @_;
130              
131 9     9   31 no strict 'refs';
  9         9  
  9         1376  
132              
133 12         14 foreach(@{ref($self) . '::ISA'}){
  12         41  
134              
135 16 100       99 if(my $code = $_->can('__initialize')){
136              
137 4         7 $code->(@_);
138             }
139             }
140              
141 12 50       60 $self->__initialize if($self->can('__initialize'));
142             }
143              
144             #
145             # default initialize
146             #
147             sub initialize{
148            
149 7     7 0 12 my ($self, @args) = @_;
150              
151             # default initialize
152            
153              
154             # if new is called with initialization values (not recommended)
155 7 50       22 if(@args % 2 == 0){
156              
157 7         12 my %args = @args;
158              
159 7         22 foreach(keys(%args)){
160              
161 0 0         $self->$_($args{$_}) if($self->can($_));
162              
163             }
164             }
165             }
166              
167             #
168             # Methods
169             #
170             sub methods{
171 0     0 0   my ($self, $class, $nested) = @_;
172              
173 0   0       $class = $class || ref($self) || $self;
174              
175 9     9   34 no strict 'refs';
  9         23  
  9         1239  
176              
177 0           my @methods = grep { defined(&{$class . '::' . $_} ) } keys(%{$class . '::'});
  0            
  0            
  0            
178              
179 0           push @methods, $self->methods($_, 1) foreach(@{ $class .'::ISA' } );
  0            
180              
181              
182 0 0         unless($nested){
183              
184 0           my %s;
185              
186 0           $s{$_}++ foreach( map { $_ =~ s/.+\:\://; $_ } @methods);
  0            
  0            
187              
188 0           return keys(%s);
189             }
190              
191 0           @methods;
192            
193             }
194              
195             #
196             # ABSTRACT method
197             #
198             sub Abstract :ATTR(CODE){
199 1     1 0 544 my ($pkg, $sym, $code, $attr_name, $data) = @_;
200              
201 9     9   44 no warnings 'redefine';
  9         10  
  9         636  
202              
203 1         30 my $n = $pkg . '::' . *{$sym}{NAME};
  1         3  
204              
205 1         4 *{$sym} = sub {
206              
207 1     1   23 die($n . ' is ABSTRACT!!!');
208            
209 1         6 };
210              
211 9     9   32 }
  9         9  
  9         35  
212              
213             #
214             # logger installing code
215             #
216             sub Log :ATTR(CODE){
217              
218 0     0 0 0 my ($pkg, $sym, $code, $attr_name, $data) = @_;
219              
220 9     9   1958 no warnings 'redefine';
  9         10  
  9         737  
221              
222 0         0 *{$sym} = sub {
223              
224 0     0   0 my ($self, @args) = @_;
225              
226 0         0 $self->logger([$pkg, *{$sym}{NAME}], \@args);
  0         0  
227              
228 0         0 $code->($self, @args);
229 0         0 };
230              
231 9     9   35 }
  9         9  
  9         24  
232              
233             sub flog{
234 0     0 0   my ($self, $code) = @_;
235              
236 0 0         unless(ref($code) eq 'CODE'){
237 0           die(ref($self) . '::flog: code ref expected');
238             }
239              
240 0           $self->{flog} = $code;
241             }
242              
243             sub logger{
244 0     0 0   my ($self, @args) = @_;
245              
246 0 0         return unless($self->{flog});
247              
248 0           $self->{flog}->($self, @args);
249             }
250              
251             1;
252              
253