File Coverage

blib/lib/Dancer/Object.pm
Criterion Covered Total %
statement 59 59 100.0
branch 10 14 71.4
condition 2 2 100.0
subroutine 14 14 100.0
pod 6 6 100.0
total 91 95 95.7


line stmt bran cond sub pod time code
1             package Dancer::Object;
2             our $AUTHORITY = 'cpan:SUKRIA';
3             #ABSTRACT: Objects base class for Dancer
4             $Dancer::Object::VERSION = '1.3514_04'; # TRIAL
5             $Dancer::Object::VERSION = '1.351404';
6             # This class is a root class for each object in Dancer.
7             # It provides basic OO tools for Perl5 without being... Moose ;-)
8              
9 204     204   57520 use strict;
  204         368  
  204         4739  
10 204     204   870 use warnings;
  204         318  
  204         3868  
11 204     204   816 use Carp;
  204         342  
  204         9943  
12 204     204   72032 use Dancer::Exception qw(:all);
  204         495  
  204         54561  
13              
14             # constructor
15             sub new {
16 4807     4807 1 58340 my ($class, %args) = @_;
17 4807         7216 my $self = \%args;
18 4807         7334 bless $self, $class;
19 4807         18325 $self->init(%args);
20 4804         75288 return $self;
21             }
22              
23             sub clone {
24 1     1 1 3 my ($self) = @_;
25 1 50       8 raise core => "The 'Clone' module is needed"
26             unless Dancer::ModuleLoader->load('Clone');
27 1         11 return Clone::clone($self);
28             }
29              
30             # initializer
31 140     140 1 1522 sub init {1}
32              
33             # meta information about classes
34             my $_attrs_per_class = {};
35             sub get_attributes {
36 351     351 1 998 my ($class, $visited_parents) = @_;
37             # $visited_parents keeps track of parent classes we already handled, to
38             # avoid infinite recursion (in case of dependencies loop). It's not stored as class singleton, otherwise
39             # get_attributes wouldn't be re-entrant.
40 351   100     2046 $visited_parents ||= {};
41 351 100       531 my @attributes = @{$_attrs_per_class->{$class} || [] };
  351         2177  
42 351         657 my @parents;
43 204     204   1406 { no strict 'refs';
  204         366  
  204         55586  
  351         502  
44 351         582 @parents = @{"$class\::ISA"}; }
  351         2773  
45 351         895 foreach my $parent (@parents) {
46             # cleanup $parent
47 177         726 $parent =~ s/'/::/g;
48 177 50       843 $parent =~ /^::/
49             and $parent = 'main' . $parent;
50              
51             # check we didn't visited it already
52 177 50       993 $visited_parents->{$parent}++
53             and next;
54              
55             # check it's a Dancer::Object
56 177 50       2431 $parent->isa(__PACKAGE__)
57             or next;
58              
59             # merge parents attributes
60 177         472 push @attributes, @{$parent->get_attributes($visited_parents)};
  177         1115  
61             }
62 351         1277 return \@attributes;
63             }
64              
65             # accessor code for normal objects
66             # (overloaded in D::O::Singleton for instance)
67             sub _setter_code {
68 11022     11022   16423 my ($class, $attr) = @_;
69             sub {
70 68490     68490   111210 my ($self, $value) = @_;
71 68490 100       90733 if (@_ == 1) {
72 61131         174643 return $self->{$attr};
73             }
74             else {
75 7359         15030 return $self->{$attr} = $value;
76             }
77 11022         34571 };
78             }
79              
80             # accessors builder
81             sub attributes {
82 2746     2746 1 13103 my ($class, @attributes) = @_;
83              
84             # save meta information
85 2746         8019 $_attrs_per_class->{$class} = \@attributes;
86              
87             # define setters and getters for each attribute
88 2746         6407 foreach my $attr (@attributes) {
89 11793         25457 my $code = $class->_setter_code($attr);
90 11793         22447 my $method = "${class}::${attr}";
91 204     204   1345 { no strict 'refs'; *$method = $code; }
  204         393  
  204         24311  
  11793         12715  
  11793         38797  
92             }
93             }
94              
95             sub attributes_defaults {
96 1092     1092 1 4369 my ($self, %defaults) = @_;
97 1092         3525 while (my ($k, $v) = each %defaults) {
98 6332 100       17868 exists $self->{$k} or $self->{$k} = $v;
99             }
100             }
101              
102             1;
103              
104             __END__