File Coverage

blib/lib/Eve/Class.pm
Criterion Covered Total %
statement 37 38 97.3
branch 6 6 100.0
condition 2 3 66.6
subroutine 11 12 91.6
pod 2 2 100.0
total 58 61 95.0


line stmt bran cond sub pod time code
1             package Eve::Class;
2              
3 29     29   26822 use strict;
  29         59  
  29         998  
4 29     29   147 use warnings;
  29         54  
  29         764  
5              
6 29     29   44802 use Contextual::Return;
  29         590925  
  29         415  
7              
8 29     29   82965 use Eve::Support;
  29         113  
  29         12896  
9              
10             our $AUTOLOAD;
11              
12             =head1 NAME
13              
14             B - a class that all other library classes use as a
15             parent.
16              
17             =head1 SYNOPSIS
18              
19             use parent qw(Eve::Class);
20              
21             sub init {
22             my ($self, %arg_hash) = @_;
23              
24             $self->{'_private_property'} = 'Private value';
25             $self->{'public_property'} = 'Public value';
26             $self->_private_method();
27             $self->public_method();
28              
29             return;
30             }
31              
32             =head1 DESCRIPTION
33              
34             B is an abstract class whose functionality is used in
35             derived classes in order to avoid initialization code duplication and
36             make routine procedures easier.
37              
38             =head2 Implicit accessors
39              
40             Another purpose of this class is to provide a mechanism that
41             simplifies access to object properties.
42              
43             Every property can be accessed using C<$foo->name> notation. If there
44             is additional processing required before getting or setting a property
45             custom getters and setters can be used. They can be defined as methods
46             by prefixing the property name with 'get_' or 'set_'. In this case
47             they will be called instead of accessing the property directly.
48              
49             package Foo;
50              
51             use parent qw(Eve::Class);
52              
53             sub init {
54             my $self = shift;
55              
56             $self->{'name'} = 'some value';
57              
58             return;
59             }
60              
61             sub set_name {
62             my ($self, $value) = @_;
63              
64             $self->{'name'} = lc($value);
65             }
66              
67             1;
68              
69             # Later ...
70              
71             $foo->name = 'Another Value';
72              
73             =head1 METHODS
74              
75             =head2 B
76              
77             This method is the constructor. It can be called both on the class
78             and on the object. Calling the constructor on an existing object
79             will return a new object of the instance's class.
80              
81             package Foo;
82              
83             use parent qw(Eve::Class);
84              
85             1;
86              
87             # Later ...
88              
89             my $foo1 = Foo->new('Your arguments here');
90             my $foo2 = $foo1->new('Your new arguments here');
91              
92             =head3 Arguments
93              
94             An arbitrary number of arguments which will be later passed to the
95             C method.
96              
97             =head3 Returns
98              
99             A new instance of the class that the method is being called on.
100              
101             =cut
102              
103             sub new {
104 142     142 1 169456 my $class = shift;
105              
106 142         534 my $self = {};
107 142   66     934 bless($self, (ref($class) or $class));
108              
109             # Calling init with the same @_
110 142         627 $self->init(@_);
111 137         593 return $self;
112             }
113              
114             =head2 B
115              
116             This method is called after an object has been instantiated using the C
117             method, all parameters that have been passed to the constructor are passed
118             to this method also.
119              
120             If you need the object to have certain properties, you need to explicitly
121             define them as hash keys inside this method.
122              
123             package Foo;
124             use parent qw(Eve::Class);
125              
126             sub init {
127             my ($self, %arg_hash) = @_;
128              
129             $self->{'_private_property'} = 'Private value';
130             $self->{'public_property'} = 'Public value';
131              
132             return;
133             }
134              
135             1;
136              
137             After that you can access the object's properties in this manner:
138              
139             my $foo1 = Foo->new();
140             print $foo1->public_property;
141             $foo1->public_property = 'Another value';
142             $foo1->_private_property = 'Whoops!';
143              
144             Please note that there is no mechanism to make properties really private or
145             protected, which means that you can access all properties from outside, no
146             matter what they are called.
147              
148             =head3 Arguments
149              
150             Note that this method should not be called directly. The C method
151             must be called instead, and all its arguments will be passed directly to
152             this method.
153              
154             =cut
155              
156 4     4 1 6 sub init {
157             # Init method stub
158             }
159              
160             sub _accessor {
161 902     902   3678 my ($self, %arg_hash) = @_;
162 902         3872 Eve::Support::arguments(\%arg_hash, my ($is_set, $name, $value));
163              
164 902 100       14156 if (not exists $self->{$name}) {
165 4         38 Eve::Error::Attribute->throw(
166             message => "Property $name does not exist");
167             }
168              
169 898         2069 my $method = ('_get', '_set')[$is_set].'_'.$name;
170 898         1036 my $result;
171 898 100       4142 if ($self->can($method)) {
172 159         494 $result = $self->$method($value);
173             } else {
174 739 100       1498 if ($is_set) {
175 6         13 $self->{$name} = $value;
176             }
177 739         1187 $result = $self->{$name}
178             }
179              
180 898         5063 return $result;
181             }
182              
183             sub AUTOLOAD : lvalue {
184 546     546   29857 my $self = shift;
185              
186 546         830 my $name = $AUTOLOAD;
187 546         5035 $name =~ s/.*:://;
188              
189             NVALUE {
190 4     4   279 Eve::Error::Attribute->throw(
191             message => "Method $name does not exist") }
192 52     52   3181 LVALUE { $self->_accessor(is_set => 1, name => $name, value => $_) }
193 850     850   43218 RVALUE { $self->_accessor(is_set => 0, name => $name, value => undef) }
194 546         5297 }
195              
196             sub DESTROY {
197 0     0     return;
198             }
199              
200             =head1 LICENSE AND COPYRIGHT
201              
202             Copyright 2012 Igor Zinovyev.
203              
204             This program is free software; you can redistribute it and/or modify it
205             under the terms of either: the GNU General Public License as published
206             by the Free Software Foundation; or the Artistic License.
207              
208             See http://dev.perl.org/licenses/ for more information.
209              
210              
211             =head1 AUTHOR
212              
213             =over 4
214              
215             =item L
216              
217             =back
218              
219             =cut
220              
221             1;