File Coverage

blib/lib/Eixo/Base/Clase.pm
Criterion Covered Total %
statement 105 137 76.6
branch 12 24 50.0
condition 3 6 50.0
subroutine 26 31 83.8
pod 0 8 0.0
total 146 206 70.8


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