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.3520';
5             # This class is a root class for each object in Dancer.
6             # It provides basic OO tools for Perl5 without being... Moose ;-)
7              
8 203     203   72205 use strict;
  203         420  
  203         5722  
9 203     203   1126 use warnings;
  203         413  
  203         4536  
10 203     203   954 use Carp;
  203         449  
  203         11479  
11 203     203   91481 use Dancer::Exception qw(:all);
  203         593  
  203         65751  
12              
13             # constructor
14             sub new {
15 4785     4785 1 70140 my ($class, %args) = @_;
16 4785         8786 my $self = \%args;
17 4785         8675 bless $self, $class;
18 4785         22042 $self->init(%args);
19 4782         91062 return $self;
20             }
21              
22             sub clone {
23 1     1 1 4 my ($self) = @_;
24 1 50       9 raise core => "The 'Clone' module is needed"
25             unless Dancer::ModuleLoader->load('Clone');
26 1         39 return Clone::clone($self);
27             }
28              
29             # initializer
30 139     139 1 1291 sub init {1}
31              
32             # meta information about classes
33             my $_attrs_per_class = {};
34             sub get_attributes {
35 349     349 1 1318 my ($class, $visited_parents) = @_;
36             # $visited_parents keeps track of parent classes we already handled, to
37             # avoid infinite recursion (in case of dependencies loop). It's not stored as class singleton, otherwise
38             # get_attributes wouldn't be re-entrant.
39 349   100     2722 $visited_parents ||= {};
40 349 100       699 my @attributes = @{$_attrs_per_class->{$class} || [] };
  349         2859  
41 349         928 my @parents;
42 203     203   1687 { no strict 'refs';
  203         470  
  203         68429  
  349         640  
43 349         649 @parents = @{"$class\::ISA"}; }
  349         2467  
44 349         1134 foreach my $parent (@parents) {
45             # cleanup $parent
46 176         817 $parent =~ s/'/::/g;
47 176 50       875 $parent =~ /^::/
48             and $parent = 'main' . $parent;
49              
50             # check we didn't visited it already
51 176 50       1119 $visited_parents->{$parent}++
52             and next;
53              
54             # check it's a Dancer::Object
55 176 50       2254 $parent->isa(__PACKAGE__)
56             or next;
57              
58             # merge parents attributes
59 176         602 push @attributes, @{$parent->get_attributes($visited_parents)};
  176         2375  
60             }
61 349         1800 return \@attributes;
62             }
63              
64             # accessor code for normal objects
65             # (overloaded in D::O::Singleton for instance)
66             sub _setter_code {
67 10960     10960   19746 my ($class, $attr) = @_;
68             sub {
69 68250     68250   133096 my ($self, $value) = @_;
70 68250 100       107450 if (@_ == 1) {
71 60915         200850 return $self->{$attr};
72             }
73             else {
74 7335         18462 return $self->{$attr} = $value;
75             }
76 10960         41751 };
77             }
78              
79             # accessors builder
80             sub attributes {
81 2730     2730 1 16322 my ($class, @attributes) = @_;
82              
83             # save meta information
84 2730         9303 $_attrs_per_class->{$class} = \@attributes;
85              
86             # define setters and getters for each attribute
87 2730         7462 foreach my $attr (@attributes) {
88 11727         30948 my $code = $class->_setter_code($attr);
89 11727         26192 my $method = "${class}::${attr}";
90 203     203   1635 { no strict 'refs'; *$method = $code; }
  203         458  
  203         29059  
  11727         15421  
  11727         47858  
91             }
92             }
93              
94             sub attributes_defaults {
95 1086     1086 1 4826 my ($self, %defaults) = @_;
96 1086         3897 while (my ($k, $v) = each %defaults) {
97 6296 100       21551 exists $self->{$k} or $self->{$k} = $v;
98             }
99             }
100              
101             1;
102              
103             __END__