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     9   165888 use Eixo::Base::Util;
  9         28  
  9         313  
4 9     9   4503 use Clone 'clone';
  9         22609  
  9         565  
5 9     9   2406 use mro;
  9         3496  
  9         69  
6              
7 9     9   257 use Attribute::Handlers;
  9         19  
  9         46  
8 9     9   222 use strict;
  9         17  
  9         304  
9 9     9   47 use warnings;
  9         16  
  9         1210  
10              
11              
12             sub import{
13 23     23   222495 my $class = shift;
14              
15 23         504 $_->import for qw(strict warnings utf8);
16             #mro->import('c3');
17              
18 23 100       127 return unless($class eq 'Eixo::Base::Clase');
19              
20 20 100 100     111 if(@_ && $_[0] eq '-norequire'){
21 3         7 shift @_;
22             }
23             else{
24 17         51 foreach my $f (my @copy = @_){
25              
26 8         80 $f =~ s!::|'!/!g;
27              
28 9     9   74 no strict 'refs';
  9         17  
  9         631  
29              
30 8         1951 require "$f.pm";
31              
32             }
33             }
34              
35 20 100       82 my @inheritance = (@_ > 0) ? @_ : $class;
36              
37 20         49 my $caller = caller;
38              
39             {
40 9     9   58 no strict 'refs';
  9         17  
  9         1590  
  20         33  
41              
42 20         40 foreach my $parent (@inheritance){
43              
44 21         30 foreach my $my_class (@{mro::get_linear_isa($parent)}){
  21         96  
45             #print "$my_class\n";
46            
47             #next if($caller->isa($my_class));
48              
49             #print "------>$caller $my_class \n";
50              
51 35         55 push @{"${caller}\:\:ISA"}, $my_class;
  35         365  
52             }
53              
54              
55             }
56              
57              
58 20         48 *{$caller . '::has'} = \&has;
  20         2057  
59              
60             };
61              
62              
63             }
64              
65              
66              
67             sub has{
68 13     13 0 782 my (%attributes) = @_;
69              
70 13         95 my $class = (caller(0))[0];
71              
72 9     9   69 no strict 'refs';
  9         16  
  9         1753  
73            
74 13         55 foreach my $attribute (keys(%attributes)){
75              
76 38         193 $class->__createSetterGetter($attribute, $attributes{$attribute});
77             }
78              
79 13         73 *{$class . '::' . '__initialize'} = sub {
80              
81 27     27   210 my $c_attributes = clone(\%attributes);
82              
83 27         64 my ($self) = @_;
84              
85 27         77 foreach(keys %$c_attributes){
86              
87 66         197 $self->{$_} = $c_attributes->{$_};
88             }
89 13         58 };
90             }
91              
92             sub __createSetterGetter{
93 17     17   38 my ($class, $attribute, $value) = @_;
94              
95 9     9   67 no strict 'refs';
  9         20  
  9         1765  
96              
97 17 50       26 unless(defined(&{$class . '::' . $attribute})){
  17         78  
98              
99 17         67 *{$class . '::' . $attribute} = sub {
100              
101 5     5   1436 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         22 $self->{$attribute};
111             }
112              
113 17         56 };
114             }
115              
116             }
117              
118             sub new{
119 4     4 0 894 my ($clase, @args) = @_;
120              
121 4         12 my $self = bless({}, $clase);
122              
123             # initialize attributes with default values from 'has'
124 4         24 $self->__chainInitialize;
125              
126             # finally call initialize method
127 4         42 $self->initialize(@args);
128              
129 4         12 $self;
130             }
131              
132              
133             sub __chainInitialize{
134 14     14   32 my ($self) = @_;
135              
136 9     9   73 no strict 'refs';
  9         19  
  9         2132  
137              
138 14         25 foreach(@{ref($self) . '::ISA'}){
  14         61  
139              
140 33 100       227 if(my $code = $_->can('__initialize')){
141              
142 5         14 $code->(@_);
143             }
144             }
145              
146 14 50       80 $self->__initialize if($self->can('__initialize'));
147             }
148              
149             #
150             # default initialize
151             #
152             sub initialize{
153            
154 9     9 0 46 my ($self, @args) = @_;
155              
156             # default initialize
157            
158              
159             # if new is called with initialization values (not recommended)
160 9 50       46 if(@args % 2 == 0){
161              
162 9         22 my %args = @args;
163              
164 9         41 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   78 no strict 'refs';
  9         34  
  9         2163  
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 900 my ($pkg, $sym, $code, $attr_name, $data) = @_;
205              
206 9     9   81 no warnings 'redefine';
  9         23  
  9         970  
207              
208 1         3 my $n = $pkg . '::' . *{$sym}{NAME};
  1         2  
209              
210 1         4 *{$sym} = sub {
211              
212 1     1   120 die($n . ' is ABSTRACT!!!');
213            
214 1         5 };
215              
216 9     9   62 }
  9         106  
  9         63  
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   3158 no warnings 'redefine';
  9         18  
  9         1146  
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   71 }
  9         23  
  9         42  
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