File Coverage

blib/lib/Class/Base.pm
Criterion Covered Total %
statement 78 83 93.9
branch 37 42 88.1
condition 21 29 72.4
subroutine 15 15 100.0
pod 8 8 100.0
total 159 177 89.8


line stmt bran cond sub pod time code
1             package Class::Base;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: useful base class for deriving other modules
4             $Class::Base::VERSION = '0.09';
5              
6 1     1   444 use strict;
  1         5  
  1         20  
7 1     1   4 use warnings;
  1         1  
  1         19  
8              
9 1     1   316 use Clone;
  1         1798  
  1         63  
10              
11             #------------------------------------------------------------------------
12             # new(@config)
13             # new(\%config)
14             #
15             # General purpose constructor method which expects a hash reference of
16             # configuration parameters, or a list of name => value pairs which are
17             # folded into a hash. Blesses a hash into an object and calls its
18             # init() method, passing the parameter hash reference. Returns a new
19             # object derived from Class::Base, or undef on error.
20             #------------------------------------------------------------------------
21              
22             sub new {
23 27     27 1 8454 my $class = shift;
24              
25             # allow hash ref as first argument, otherwise fold args into hash
26 27 100 100     140 my $config = defined $_[0] && UNIVERSAL::isa($_[0], 'HASH')
27             ? shift : { @_ };
28              
29 1     1   5 no strict 'refs';
  1         1  
  1         152  
30             my $debug = defined $config->{ debug }
31             ? $config->{ debug }
32             : defined $config->{ DEBUG }
33             ? $config->{ DEBUG }
34 27 100 100     62 : ( do { local $^W; ${"$class\::DEBUG"} } || 0 );
    100          
35              
36             my $self = bless {
37 27   66     134 _ID => $config->{ id } || $config->{ ID } || $class,
38             _DEBUG => $debug,
39             _ERROR => '',
40             }, $class;
41              
42 27   66     75 return $self->init($config)
43             || $class->error($self->error());
44             }
45              
46              
47             #------------------------------------------------------------------------
48             # init()
49             #
50             # Initialisation method called by the new() constructor and passing a
51             # reference to a hash array containing any configuration items specified
52             # as constructor arguments. Should return $self on success or undef on
53             # error, via a call to the error() method to set the error message.
54             #------------------------------------------------------------------------
55              
56             sub init {
57 14     14 1 56 return $_[0];
58             }
59              
60              
61             #------------------------------------------------------------------------
62             # clone()
63             #
64             # Method to perform a simple clone of the current object hash and return
65             # a new object.
66             #------------------------------------------------------------------------
67              
68             sub clone {
69 2     2 1 832 return Clone::clone(shift);
70             }
71              
72              
73             #------------------------------------------------------------------------
74             # error()
75             # error($msg, ...)
76             #
77             # May be called as a class or object method to set or retrieve the
78             # package variable $ERROR (class method) or internal member
79             # $self->{ _ERROR } (object method). The presence of parameters indicates
80             # that the error value should be set. Undef is then returned. In the
81             # abscence of parameters, the current error value is returned.
82             #------------------------------------------------------------------------
83              
84             sub error {
85 13     13 1 1765 my $self = shift;
86 13         12 my $errvar = do {
87             # get a reference to the object or package variable we're munging
88 1     1   6 no strict qw( refs );
  1         1  
  1         437  
89 13 100       48 ref $self ? \$self->{ _ERROR } : \${"$self\::ERROR"};
  4         11  
90             };
91              
92 13 100       27 if (@_) {
93             # don't join if first arg is an object (may force stringification)
94 5 50       16 $$errvar = ref($_[0]) ? shift : join('', @_);
95 5         36 return undef;
96             }
97              
98 8         24 return $$errvar;
99             }
100              
101              
102              
103             #------------------------------------------------------------------------
104             # id($new_id)
105             #
106             # Method to get/set the internal _ID field which is used to identify
107             # the object for the purposes of debugging, etc.
108             #------------------------------------------------------------------------
109              
110             sub id {
111 16     16 1 1327 my $self = shift;
112              
113             # set _ID with $obj->id('foo')
114 16 100 100     59 return ($self->{ _ID } = shift) if ref $self && @_;
115              
116             # otherwise return id as $self->{ _ID } or class name
117 14         16 my $id;
118 14 100       26 $id = $self->{ _ID } if ref $self;
119 14   33     28 $id ||= ref($self) || $self;
      66        
120              
121 14         39 return $id;
122             }
123              
124              
125             #------------------------------------------------------------------------
126             # params($vals, @keys)
127             # params($vals, \@keys)
128             # params($vals, \%keys)
129             #
130             # Utility method to examine the $config hash for any keys specified in
131             # @keys and copy the values into $self. Keys should be specified as a
132             # list or reference to a list of UPPER CASE names. The method looks
133             # for either the name in either UPPER or lower case in the $config
134             # hash and copies the value, if defined, into $self. The keys can
135             # also be specified as a reference to a hash containing default values
136             # or references to handler subroutines which will be called, passing
137             # ($self, $config, $UPPER_KEY_NAME) as arguments.
138             #------------------------------------------------------------------------
139              
140             sub params {
141 8     8 1 42 my $self = shift;
142 8         9 my $vals = shift;
143 8         17 my ($keys, @names);
144 8         0 my ($key, $lckey, $default, $value, @values);
145              
146              
147 8 50       12 if (@_) {
148 8 50       18 if (ref $_[0] eq 'ARRAY') {
    100          
149 0         0 $keys = shift;
150 0         0 @names = @$keys;
151 0         0 $keys = { map { ($_, undef) } @names };
  0         0  
152             }
153             elsif (ref $_[0] eq 'HASH') {
154 2         4 $keys = shift;
155 2         5 @names = keys %$keys;
156             }
157             else {
158 6         13 @names = @_;
159 6         11 $keys = { map { ($_, undef) } @names };
  18         31  
160             }
161             }
162             else {
163 0         0 $keys = { };
164             }
165              
166 8         12 foreach $key (@names) {
167 24         33 $lckey = lc $key;
168              
169             # look for value provided in $vals hash
170             defined($value = $vals->{ $key })
171 24 100       43 || ($value = $vals->{ $lckey });
172              
173             # look for default which may be a code handler
174 24 100 100     44 if (defined ($default = $keys->{ $key })
175             && ref $default eq 'CODE') {
176 2         4 eval {
177 2         5 $value = &$default($self, $key, $value);
178             };
179 2 50       19 return $self->error($@) if $@;
180             }
181             else {
182 22 100       38 $value = $default unless defined $value;
183 22 100       35 $self->{ $key } = $value if defined $value;
184             }
185 24         27 push(@values, $value);
186 24         35 delete @$vals{ $key, lc $key };
187             }
188 8 50       25 return wantarray ? @values : \@values;
189             }
190              
191              
192             #------------------------------------------------------------------------
193             # debug(@args)
194             #
195             # Debug method which prints all arguments passed to STDERR if and only if
196             # the appropriate DEBUG flag(s) are set. If called as an object method
197             # where the object has a _DEBUG member defined then the value of that
198             # flag is used. Otherwise, the $DEBUG package variable in the caller's
199             # class is used as the flag to enable/disable debugging.
200             #------------------------------------------------------------------------
201              
202             sub debug {
203 16     16 1 79 my $self = shift;
204 16         18 my ($flag);
205              
206 16 100 66     53 if (ref $self && defined $self->{ _DEBUG }) {
207 15         19 $flag = $self->{ _DEBUG };
208             }
209             else {
210             # go looking for package variable
211 1     1   6 no strict 'refs';
  1         14  
  1         92  
212 1   33     18 $self = ref $self || $self;
213 1         2 $flag = ${"$self\::DEBUG"};
  1         5  
214             }
215              
216 16 100       28 return unless $flag;
217              
218 8         16 print STDERR '[', $self->id, '] ', @_;
219             }
220              
221              
222             #------------------------------------------------------------------------
223             # debugging($flag)
224             #
225             # Method to turn debugging on/off (when called with an argument) or to
226             # retrieve the current debugging status (when called without). Changes
227             # to the debugging status are propagated to the $DEBUG variable in the
228             # caller's package.
229             #------------------------------------------------------------------------
230              
231             sub debugging {
232 23     23 1 3213 my $self = shift;
233              
234 1     1   5 no strict 'refs';
  1         2  
  1         67  
235              
236 23 100       49 my $dbgvar = ref $self ? \$self->{ _DEBUG } : \${"$self\::DEBUG"};
  6         17  
237              
238 23 100       78 return @_ ? ($$dbgvar = shift)
239             : $$dbgvar;
240              
241             }
242              
243              
244             1;
245              
246             __END__