File Coverage

lib/Badger/Class.pm
Criterion Covered Total %
statement 436 468 93.1
branch 105 170 61.7
condition 42 75 56.0
subroutine 97 110 88.1
pod 48 48 100.0
total 728 871 83.5


line stmt bran cond sub pod time code
1             #========================================================================
2             #
3             # Badger::Class
4             #
5             # DESCRIPTION
6             # Module implementing metaclass functionality for composing classes
7             # (equivalent to C) and other class-related actions.
8             #
9             # AUTHOR
10             # Andy Wardley
11             #
12             #========================================================================
13              
14             package Badger::Class;
15              
16 88     6524   9799 use strict;
  87         180  
  87         2082  
17 81     81   4158 use warnings;
  80         1153  
  80         1775  
18 77     77   2727 use Carp;
  77         174  
  77         4035  
19 75     75   1930 use base 'Badger::Exporter';
  74         159  
  74         30409  
20             use constant {
21 72         38617 base_id => 'Badger',
22             BCLASS => 'Badger::Class',
23             FILESYSTEM => 'Badger::Filesystem',
24             CONSTANTS => 'Badger::Constants',
25             EXPORTER => 'Badger::Exporter',
26             MIXIN => 'Badger::Mixin',
27             CODECS => 'Badger::Codecs',
28             UTILS => 'Badger::Utils',
29             DEBUGGER => 'Badger::Debug',
30             CONFIG => 'Badger::Class::Config',
31             METHODS => 'Badger::Class::Methods',
32             VARS => 'Badger::Class::Vars',
33             MESSAGES => 'MESSAGES',
34             VERSION => 'VERSION',
35             MIXINS => 'MIXINS',
36             THROWS => 'THROWS',
37             ISA => 'ISA',
38             NO_VALUE => "You didn't specify a value for the '%s' option",
39 74     74   1574 };
  72         120  
40             use Badger::Constants
41 73     73   27447 'DELIMITER SCALAR ARRAY HASH CODE PKG REFS ONCE TRUE FALSE LOADED';
  70         2835  
  70         339  
42             use overload
43 70         448 '""' => 'name',
44 73     73   76359 fallback => 1;
  70         62846  
45              
46             our $VERSION = 0.01;
47             our $DEBUG = 0 unless defined $DEBUG;
48             our $LOADED = { };
49              
50             BEGIN {
51             # generate a compile time constant from $DEBUG
52 72     72   20979 *DEBUG = sub() { $DEBUG };
  28485     28485   40208  
53             }
54              
55             #-----------------------------------------------------------------------
56             # Methods that we delegate to other modules. The module name is
57             # determined by calling the constant method (first argument on RHS
58             # which is auto-quoted by '=>', e.g. 'METHODS', 'ALIASES') against
59             # $self, allowing for sub-classes of Badger::Class to define different
60             # modules for this task. The second argument on the RHS is the method.
61             # The methods are generated a little further on in this module.
62             #-----------------------------------------------------------------------
63              
64             our $DELEGATES = {
65             # note the first argument on RHS is quto-quoted by =>
66             accessors => [ METHODS => 'accessors' ],
67             codec => [ CODECS => 'export_codec' ],
68             codecs => [ CODECS => 'export_codecs' ],
69             config => [ CONFIG => 'export' ],
70             constants => [ CONSTANTS => 'export' ],
71             filesystem => [ FILESYSTEM => 'export' ],
72             hash_methods => [ METHODS => 'hash' ],
73             mutators => [ METHODS => 'mutators' ],
74             slots => [ METHODS => 'slots' ],
75             init_method => [ METHODS => 'initialiser' ],
76             auto_can => [ METHODS => 'auto_can' ],
77             utils => [ UTILS => 'export' ],
78             vars => [ VARS => 'vars' ],
79             };
80              
81             *get_methods = \&accessors;
82             *set_methods = \&mutators;
83              
84              
85             #-----------------------------------------------------------------------
86             # Define exportable items and export hooks (see Badger::Exporter)
87             #-----------------------------------------------------------------------
88              
89             our $EXPORT_ANY = ['BCLASS'];
90             our $EXPORT_FAIL = \&_export_fail;
91             our $EXPORT_HOOKS = {
92             debug => [\&_debug_hook, 1],
93             dumps => [\&_dumps_hook, 1],
94             map { $_ => \&_export_hook }
95             qw(
96             base uber mixin mixins version constant constants words vars
97             config exports throws messages utils codec codecs filesystem
98             hooks methods alias slots accessors mutators get_methods
99             set_methods hash_methods init_method auto_can overload as_text
100             is_true
101             )
102             };
103              
104              
105             sub export {
106 1502     1502 1 5743 my ($class, $package, @args) = @_;
107 70     72   462 no strict REFS;
  72         598  
  70         2596  
108 70     72   354 no warnings ONCE;
  72         421  
  70         33983  
109 1502   100     1770 ${ $package.PKG.LOADED } ||= 1; # add $BADGER_LOADED to mark our scent
  1502         10919  
110 1502         5051 $class->SUPER::export($package, @args);
111             }
112              
113              
114             sub _export_hook {
115 8451     8451   13107 my ($class, $target, $key, $symbols) = @_;
116              
117 8451 50       11477 croak sprintf(NO_VALUE, $key)
118             unless @$symbols;
119              
120 8451         11836 class($target, $class)->$key(shift @$symbols);
121             }
122              
123              
124             sub _export_fail {
125 76     76   166 my ($class, $target, $key, $symbols, $import) = @_;
126              
127             # look for any additional export hooks defined in $HOOKS, e.g.
128             # by a subclass or poked in via the hooks() method
129 76   50     128 my $hook = class($class)->hash_value( HOOKS => $key ) || return;
130              
131 76 50       168 croak sprintf(NO_VALUE, $key)
132             unless @$symbols;
133              
134             # We use the two-argument call to class() which tells it that we want
135             # a $class metaclass object rather than the default of Badger::Class.
136             # This is because subclasses may be calling this method so $class isn't
137             # always going to be Badger::Class
138 76         167 class($target, $class)->$hook(shift @$symbols);
139             }
140              
141              
142             sub _debug_hook {
143 1182     1182   2274 my ($class, $target, $key, $debug) = @_;
144 1182 50       3491 $debug = { default => $debug }
145             unless ref $debug eq HASH;
146 1182         5027 _autoload($class->DEBUGGER)->export($target, %$debug);
147             }
148              
149             sub _dumps_hook {
150 140     140   348 my ($class, $target, $key, $dumps) = @_;
151 140         459 _autoload($class->DEBUGGER)->export($target, dumps => $dumps);
152             }
153              
154              
155              
156             #-----------------------------------------------------------------------
157             # Define a lexical scope to enclose class lookup tables
158             #-----------------------------------------------------------------------
159              
160             # Badger::Class and each of its subclasses have their own metaclass
161             # table mapping class names to objects.
162             my $METACLASSES = { };
163              
164             {
165             # class/package name - define this up-front so we can use it below
166             sub CLASS {
167             # first argument is object or class name, otherwise return caller
168 131 100 33 131 1 1137 @_ ? (ref $_[0] || $_[0])
169             : (caller())[0];
170             }
171              
172             # Sorry if this messes with your head. We want class() and classes()
173             # methods that create Badger::Class objects. However, we also want
174             # Badger::Class to be subclassable (e.g. Badger::Factory::Class), where
175             # class() and classes() return the subclass objects instead of the usual
176             # Badger::Class. So we have an UBER() class method whose job it is to
177             # create the class() and classes() methods for the relevant metaclass
178              
179             sub UBER {
180             # $pkg is the metaclass name, e.g. Badger::Class, but can also be
181             # subclasses, e.g. Badger::Factory::Class
182 101   50 101 1 310 my $pkg = shift || __PACKAGE__;
183              
184             # $CLASSES is a lookup table mapping package names to Badger::Class
185             # objects. We need a new lookup table for each subclass of
186             # Badger::Class, so we reuse/create such a table in $METACLASSES,
187             # indexed by the metaclass name, e.g. Badger::Class, etc.
188 101   50     536 my $CLASSES = $METACLASSES->{ $pkg } ||= { };
189              
190             # We want to keep the class() subroutine as fast as possible as it
191             # gets called often. It's a tiny bit faster to declare a variable
192             # outside the closure and reuse it, rather than defining a new
193             # variable each time the closure is called. Ho hum.
194 101         137 my $class;
195              
196             # The class() subroutine is used to fetch/create a Badger::Class
197             # object for a package name. The first argument is the class name,
198             # or the caller's package if undefined and we look it up in $CLASSES.
199             # If we get a second argument then we're being asked to lookup an
200             # entry for a subclass of Badger::Class, e.g. Badger::Factory::Class,
201             # so we first lookup the correct $METACLASS table.
202             my $class_sub = sub {
203 12881 100   12881   21353 $class = @_ ? shift : (caller())[0];
204 12881   66     25356 $class = ref $class || $class;
205             return @_
206             ? $METACLASSES->{ $_[0] }->{ $class } ||= $_[0]->new($class)
207 12881 100 66     44714 : $CLASSES->{ $class } ||= $pkg->new($class);
      66        
208 101         395 };
209              
210             # The classes() method returns a list of Badger::Class objects for
211             # each class in the inheritance chain, starting with the object
212             # itself, followed by each base class, their base classes, and so on.
213             # As with class(), we use a generator to create a closure for the
214             # subroutine to allow the the class object name to be parameterised.
215             my $classes_sub = sub {
216 2   33 2   6 $class = shift || (caller())[0];
217 2         3 $class_sub->($class)->heritage;
218 101         300 };
219              
220 70     71   451 no strict REFS;
  71         269  
  70         2189  
221 70     71   335 no warnings 'redefine';
  71         267  
  70         19962  
222 101         178 *{ $pkg.PKG.'CLASS' } = \&CLASS;
  101         465  
223 101         163 *{ $pkg.PKG.'class' } = $class_sub;
  101         322  
224 101         195 *{ $pkg.PKG.'bclass' } = $class_sub; # plan B
  101         349  
225 101         151 *{ $pkg.PKG.'classes' } = $classes_sub;
  101         441  
226 101         177 *{ $pkg.PKG.'_autoload' } = \&_autoload;
  101         312  
227              
228 101         785 $pkg->export_any('CLASS', 'class', 'bclass', 'classes');
229             }
230              
231             # call the UBER method to generate class() and classes() for this module
232             __PACKAGE__->UBER;
233             }
234              
235              
236              
237             #-----------------------------------------------------------------------
238             # generate additional delegate methods listed in $DELEGATES
239             #-----------------------------------------------------------------------
240              
241             class(CLASS)->methods(
242             map {
243             my $info = $DELEGATES->{ $_ };
244             my ($module, $method) = @$info;
245             $_ => sub {
246 2404     2404   2919 my $self = shift;
247 2404         7287 _autoload($self->$module)->$method($self->{ name }, @_);
248 2404         4327 return $self;
249             };
250             }
251             keys %$DELEGATES
252             );
253              
254              
255             #-----------------------------------------------------------------------
256             # constructor method
257             #-----------------------------------------------------------------------
258              
259             sub new {
260 1711     1711 1 2843 my ($class, $package) = @_;
261 1711   33     3779 $package = ref $package || $package;
262 70     71   618 no strict 'refs';
  71         421  
  70         34168  
263             bless {
264             name => $package,
265 1711         2078 symbols => \%{"${package}::"},
  1711         32473  
266             }, $class;
267             }
268              
269             sub id {
270 54     54 1 112 my $self = shift;
271             return @_
272             ? $self->{ id } = shift
273 54 50 66     246 : $self->{ id } ||= do {
274 35         56 my $pkg = $self->{ name };
275 35         110 my $base = $self->base_id; # base to remove, e.g. Badger
276 35 100       99 if ($base eq $pkg) {
277 1 50       9 $pkg = $1 if $pkg =~ /(\w+)$/; # Badger - Badger --> Badger
278             } else {
279 34         343 $pkg =~ s/^${base}:://; # Badger::X::Y - Badger --> X::Y
280             }
281 35         123 $pkg =~ s/::/./g; # X::Y --> X.Y
282 35         290 lc $pkg; # X.Y --> x.y
283             };
284             }
285              
286              
287             #-----------------------------------------------------------------------
288             # methods to access symbol table
289             #-----------------------------------------------------------------------
290              
291             *pkg = \&name;
292 50371     50371 1 118358 sub name { $_[0]->{ name } }
293 0     0 1 0 sub symbols { $_[0]->{ symbols } }
294 0     0 1 0 sub symbol { $_[0]->{ symbols }->{ $_[1] } }
295 0 0   0 1 0 sub scalar_ref { *{ $_[0]->{ symbols }->{ $_[1] } || return }{ SCALAR } }
  0         0  
296 0 0   0 1 0 sub array_ref { *{ $_[0]->{ symbols }->{ $_[1] } || return }{ ARRAY } }
  0         0  
297 0 0   0 1 0 sub hash_ref { *{ $_[0]->{ symbols }->{ $_[1] } || return }{ HASH } }
  0         0  
298 0 0   0 1 0 sub code_ref { *{ $_[0]->{ symbols }->{ $_[1] } || return }{ CODE } }
  0         0  
299 0 0   0 1 0 sub glob_ref { *{ $_[0]->{ symbols }->{ $_[1] } || return }{ GLOB } }
  0         0  
300 0 0   0 1 0 sub scalar { ${ scalar_ref(@_) || return } }
  0         0  
301 0 0   0 1 0 sub array { @{ array_ref(@_) || return } }
  0         0  
302 0 0   0 1 0 sub hash { %{ hash_ref(@_) || return } }
  0         0  
303              
304             sub import_symbol {
305 930     930 1 1576 my ($self, $symbol, $ref) = @_;
306 70     70   459 no strict REFS;
  70         174  
  70         2214  
307 70     70   359 no warnings ONCE;
  70         454  
  70         5580  
308 930         943 *{ $self->{ name }.PKG.$symbol } = $ref;
  930         4890  
309             }
310              
311              
312             #-----------------------------------------------------------------------
313             # methods for accessing class variables that DTRT in subclasses
314             #-----------------------------------------------------------------------
315              
316             sub var {
317 230     230 1 321 my $self = shift;
318 230         311 my $name = shift;
319 70     70   414 no strict REFS;
  70         136  
  70         2243  
320 70     70   336 no warnings ONCE;
  70         145  
  70         6639  
321              
322             # _debug("Looking for $self->{ name }", PKG, $name, " args: ", scalar(@_), " => ", join(', ', @_), "\n");
323             return @_
324 105         514 ? (${ $self->{name}.PKG.$name } = shift)
325 230 100       472 : ${ $self->{name}.PKG.$name };
  125         448  
326             }
327              
328             sub var_default {
329 44     44 1 122 my ($self, $name, $default) = @_;
330 70     70   403 no strict REFS;
  70         114  
  70         2178  
331 70     70   329 no warnings ONCE;
  70         139  
  70         5706  
332              
333 44   66     70 return ${ $self->{name}.PKG.$name }
  44         408  
334             ||= $default;
335             }
336              
337             sub any_var {
338 265     265 1 327 my $self = shift;
339 265         322 my $name = shift;
340 70     70   381 no strict REFS;
  70         129  
  70         11664  
341              
342             # remove any leading '$'
343 265         394 $name =~ s/^\$//;
344              
345 265         419 foreach my $pkg ($self->heritage) {
346 595 50       818 _debug("looking for $name in $pkg\n") if DEBUG;
347 595 100       569 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  179         242  
  595         753  
348             }
349              
350 86         417 return undef;
351             }
352              
353             sub any_var_in {
354 116     116 1 172 my $self = shift;
355 116 100       272 my $names = @_ == 1 ? shift : [@_];
356 116         164 my ($pkg, $name);
357 70     70   461 no strict REFS;
  70         90  
  70         13464  
358              
359 116 100       480 $names = [ split DELIMITER, $names ]
360             unless ref $names eq ARRAY;
361              
362             # remove any leading '$'
363 116         549 $names = [ map { s/^\$//; $_ } @$names ];
  152         194  
  152         336  
364              
365 116         271 foreach $pkg ($self->heritage) {
366 245         342 foreach $name (@$names) {
367 380 50       474 _debug("looking for $name in $pkg\n") if DEBUG;
368 380 100       341 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  84         112  
  380         524  
369             }
370             }
371              
372 32         112 return undef;
373             }
374              
375             sub all_vars {
376 2170     2170 1 2593 my ($self, $name) = @_;
377 2170         2415 my $pkg = $self->{ name };
378 2170         2120 my ($value, @values);
379 70     70   418 no strict REFS;
  70         123  
  70         2248  
380 70     70   325 no warnings ONCE;
  70         112  
  70         36428  
381              
382             # remove any leading '$'
383 2170         2280 $name =~ s/^\$//;
384              
385             # _debug("all_vars() caller: ", join(', ', caller()), "\n");
386              
387 2170         3096 foreach my $pkg ($self->heritage) {
388 6683 50 0     7200 _debug("looking for $name in ", $pkg || "UNDEF", "\n") if DEBUG;
389             push(@values, $value)
390 6683 100       5519 if defined ($value = ${ $pkg.PKG.$name });
  6683         7819  
391 6683 50 33     7417 _debug("got: $value\n") if DEBUG && $value;
392             }
393              
394 2170 100       4666 return wantarray ? @values : \@values;
395              
396             }
397              
398             sub list_vars {
399 155     155 1 207 my $self = shift; # must remove these from @_ here
400 155         180 my $name = shift;
401 155         288 my $vars = $self->all_vars($name);
402 155         210 my (@merged, $list);
403              
404             # remove any leading '$'
405 155         223 $name =~ s/^\$//;
406              
407 155         243 foreach $list (@_, @$vars) { # use whatever is left in @_ here
408 159 100       292 next unless defined $list;
409 87 100       209 if (ref $list eq ARRAY) {
410 66 50       147 next unless @$list;
411 66         162 push(@merged, @$list);
412             }
413             else {
414 21         32 push(@merged, $list);
415             }
416             }
417              
418             # return \@merged;
419              
420             # NOTE TO SELF: this causes problems when doing something like
421             # foo( something_that_calls_list_vars() ) because list_vars assumed
422             # list context when we actually want a scalar ref. Must find where
423             # this is and fix it.
424 155 100       608 return wantarray ? @merged : \@merged;
425              
426             }
427              
428             sub hash_vars {
429 74     74 1 116 my $self = shift; # must remove these from @_ here
430 74         91 my $name = shift;
431 74         147 my $vars = $self->all_vars($name);
432 74         118 my (%merged, $hash);
433              
434             # remove any leading '$'
435 74         126 $name =~ s/^\$//;
436              
437             # reverse the package vars so we get base classes first, followed by subclass,
438             # then we add any additional arguments on as well in the order specified
439 74         152 foreach $hash ( reverse(@$vars), @_ ) {
440 141 100       307 next unless defined $hash;
441 46 50       143 unless (ref $hash eq HASH) {
442 0         0 warn "Ignoring $name configuration option (not a hash ref): $hash\n";
443 0         0 next;
444             }
445 46         290 @merged{ keys %$hash } = values %$hash;
446             }
447              
448 74         217 return \%merged;
449             }
450              
451             sub hash_value {
452 1939     1939 1 2991 my ($self, $name, $item, $default) = @_;
453              
454             # remove any leading '$'
455 1939         2646 $name =~ s/^\$//;
456              
457             # _debug("hash_value() caller: ", join(', ', caller()), "\n");
458              
459 1939         3108 foreach my $hash ($self->all_vars($name)) {
460 1944 50       3320 next unless ref $hash eq HASH;
461             return $hash->{ $item }
462 1944 100       6187 if defined $hash->{ $item };
463             }
464              
465 0         0 return $default;
466             }
467              
468              
469             #-----------------------------------------------------------------------
470             # Methods to return immediate parent classes and all ancestor classes.
471             #-----------------------------------------------------------------------
472              
473             sub parents {
474 721     721 1 752 my $self = shift;
475 721   33     1145 my $class = ref $self || $self;
476 721         866 my $pkg = $self->{ name };
477 721   66     1537 my $parents = $self->{ parents } ||= do {
478 70     70   465 no strict REFS;
  70         133  
  70         18077  
479              
480             # make sure the module is loaded before we go looking at its @ISA
481 480         1030 _autoload($pkg);
482             [
483 408         636 map { class($_) } # parents are immediate
484 480         537 @{ $pkg.PKG.ISA } # superclasses defined in @ISA
  480         1403  
485             ];
486             };
487              
488             return wantarray
489 721 50       1998 ? @$parents
490             : $parents;
491             }
492              
493             sub heritage {
494 2580     2580 1 2417 my $self = shift;
495 2580   66     4250 my $heritage = $self->{ heritage } ||= do {
496 221         421 my @pending = ($self);
497 221         309 my (%seen, $item, @order);
498 221         546 while (@pending) {
499 720 50       1278 next unless defined ($item = pop @pending);
500 720         995 unshift(@order, $item);
501 720         773 push(@pending, reverse @{ $item->parents });
  720         2041  
502             }
503 221         420 [ reverse grep { ! $seen{$_}++ } @order ];
  720         938  
504             };
505             return wantarray
506 2580 50       5431 ? @$heritage
507             : $heritage;
508             }
509              
510              
511             #-----------------------------------------------------------------------
512             # class configuration methods - also available as import hooks
513             #-----------------------------------------------------------------------
514              
515             sub base {
516 2127     2127 1 2556 my $self = shift;
517 2127 50       3589 my $bases = @_ == 1 ? shift : [ @_ ];
518 2127         2593 my $pkg = $self->{ name };
519              
520 2127 50       14159 $bases = [ split(DELIMITER, $bases) ]
521             unless ref $bases eq ARRAY;
522              
523             # add each of $bases to @ISA and autoload it
524 2127         3994 foreach my $base (@$bases) {
525 70     70   430 no strict REFS;
  70         94  
  70         25041  
526 2312 100       18200 next if $pkg->isa($base);
527 2061 50       3646 _debug("Adding $pkg base class $base\n") if DEBUG;
528 2061         2233 push @{ $pkg.PKG.ISA }, $base;
  2061         23471  
529 2061         5918 _autoload($base);
530             }
531 2127         4433 return $self;
532             }
533              
534             sub mixin {
535 3     3 1 4 my $self = shift;
536 3 50       15 my $mixins = @_ == 1 ? shift : [ @_ ];
537              
538 3 50       18 $mixins = [ split(DELIMITER, $mixins) ]
539             unless ref $mixins eq ARRAY;
540              
541 3         6 foreach my $name (@$mixins) {
542             # $name = $target . $name if $name =~ /^::/;
543             # $self->debug("mixing $name into $self\n") if $DEBUG;
544 3         5 _autoload($name)->mixin($self->{ name });
545             }
546              
547 3         7 return $self;
548             }
549              
550             sub mixins {
551 3     3 1 5 my $self = shift;
552 3         5 $self->base(MIXIN);
553 3         13 $self->{ name }->mixins(@_);
554 3         6 return $self;
555              
556 0 0       0 my $syms = @_ == 1 ? shift : [ @_ ];
557 0         0 my $mixins = $self->var_default(MIXINS, [ ]);
558              
559 0 0       0 $syms = [ split(DELIMITER, $syms) ]
560             unless ref $syms eq ARRAY;
561              
562             # $mixins->{ $_ }
563 0         0 push(@$mixins, @$syms);
564              
565 0 0       0 $self->debug("$self MIXINS are: ", $self->dump_data_inline($mixins), "\n") if DEBUG;
566              
567 0         0 $self->exports( any => $syms );
568              
569             }
570              
571             sub version {
572 1384     1384 1 2340 my ($self, $version) = @_;
573 1384         1894 my $pkg = $self->{ name };
574 70     70   451 no strict 'refs';
  70         114  
  70         17662  
575 1384 50       2229 _debug("Defining $pkg version $version\n") if DEBUG;
576              
577             # define $VERSION and VERSION()
578 1384         4363 *{ $pkg.PKG.VERSION } = \$version
579 1384         7558 unless defined ${ $pkg.PKG.VERSION }
580 1384 50 33     1576 && ${ $pkg.PKG.VERSION };
  0         0  
581 1384     6   4175 *{ $pkg.PKG.VERSION } = sub() { $version }
  6         28  
582 1384 50       1679 unless defined &{ $pkg.PKG.VERSION }; # CHECK THIS - was 'version'
  1384         7030  
583              
584 1384         3161 return $self;
585             }
586              
587             sub constant {
588 797     797 1 1081 my $self = shift;
589 797 100       1567 my $constants = @_ == 1 ? shift : { @_ };
590 797         1110 my $pkg = $self->{ name };
591              
592             # split string into pairs of assignments, e.g. "foo=bar, baz=bam"
593             $constants = {
594 797 50       1647 map { split /\s*=>?\s*/ }
  0         0  
595             split(DELIMITER, $constants)
596             } unless ref $constants eq HASH;
597              
598              
599 797         3143 while (my ($name, $value) = each %$constants) {
600 70     70   433 no strict REFS;
  70         194  
  70         11191  
601 2449         2864 my $v = $value; # new lexical variable to bind in closure
602 2449 50       3060 _debug("Defining $pkg constant $name => $value\n") if DEBUG;
603 2449     0   10306 *{ $pkg.PKG.$name } = sub() { $value };
  2449         12526  
  0         0  
604             }
605 797         1650 return $self;
606             }
607              
608             sub words {
609 493     493 1 1062 my $self = shift;
610 493 50       1019 my $words = @_ == 1 ? shift : [ @_ ];
611 493         984 my $pkg = $self->{ name };
612              
613 493 50       3518 $words = [ split(DELIMITER, $words) ]
614             unless ref $words eq ARRAY;
615              
616 493         1121 foreach (@$words) {
617 70     70   413 no strict REFS;
  70         95  
  70         15480  
618 1287         2023 my $word = $_; # new lexical variable to bind in closure
619 1287 50       2085 _debug("Defining $pkg word $word\n") if DEBUG;
620 1287     0   6218 *{ $pkg.PKG.$word } = sub() { $word };
  1287         5519  
  0         0  
621             }
622 493         1204 return $self;
623             }
624              
625             sub exports {
626 695     695 1 935 my $self = shift;
627 695         948 my $pkg = $self->{ name };
628 695         1649 $self->base(EXPORTER);
629 695         3312 $pkg->exports(@_);
630 695         1239 return $self;
631             }
632              
633             sub throws {
634 2     2 1 5 my ($self, $throws) = @_;
635 2         10 $self->import_symbol(THROWS, \$throws);
636 2         4 return $self;
637             }
638              
639             sub messages {
640 638     638 1 856 my $self = shift;
641 638 100 66     2331 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
642 638         1001 my $pkg = $self->{ name };
643 70     70   407 no strict REFS;
  70         118  
  70         2171  
644 70     70   372 no warnings ONCE;
  70         112  
  70         12919  
645              
646             # if there aren't any existing $MESSAGES then we can store
647             # $messages in it and be done, otherwise we have to merge.
648 638         639 my $messages = ${ $pkg.PKG.MESSAGES };
  638         2527  
649              
650 638 100       1131 if ($messages) {
651 1 50       2 _debug("merging $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
652 1         5 @$messages{ keys %$args } = values %$args;
653             }
654             else {
655 637 50       1111 _debug("adding $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
656 637         858 ${ $pkg.PKG.MESSAGES } = $messages = $args;
  637         1417  
657             }
658              
659 638         1098 return $self;
660             }
661              
662             sub method {
663 25     25 1 52 my $self = shift;
664 25         34 my $name = shift;
665 70     70   474 no strict REFS;
  70         129  
  70         2141  
666 70     70   371 no warnings 'redefine';
  70         140  
  70         11766  
667              
668             # method($name) can be used to fetch a method/sub
669 25 100       80 return $self->{ name }->can($name)
670             unless @_;
671              
672             # method($name => $code) or $method($name => $value) to define method
673 21         28 my $code = shift;
674 21 50       38 _debug("defining method: $self\::$name => $code\n") if DEBUG;
675              
676 21         95 *{ $self->{name}.PKG.$name } = ref $code eq CODE
677             ? $code
678 21 100   3   61 : sub { $code }; # constant method returns value
  3         5  
679              
680 21         54 return $self;
681             }
682              
683             sub methods {
684 713     713 1 1119 my $self = shift;
685 713 100 66     4771 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
686 713         1362 my $pkg = $self->{ name };
687 70     70   404 no strict REFS;
  70         128  
  70         2243  
688 70     70   346 no warnings 'redefine';
  70         131  
  70         11651  
689              
690 713         3151 while (my ($name, $code) = each %$args) {
691 4967 50       6479 _debug("defining method: $self\::$name => $code\n") if DEBUG;
692 4967         20907 *{ $pkg.PKG.$name }
693 4967 100   1   6689 = ref $code eq CODE ? $code : sub { $code };
  1         3  
694             }
695 713         2137 return $self;
696             }
697              
698             sub alias {
699 92     92 1 175 my $self = shift;
700 92 100 66     526 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
701 92         202 my $pkg = $self->{ name };
702 70     70   411 no strict REFS;
  70         86  
  70         55823  
703              
704 92         445 while (my ($names, $code) = each %$args) {
705 97 50       237 _debug("defining alias: $self\::$names => $code\n") if DEBUG;
706 97 100 33     320 $code = $self->method($code)
707             || croak "Invalid method specified for '$names' alias: $code"
708             unless ref $code eq CODE;
709 97         428 foreach my $name (split(DELIMITER, $names)) {
710 97         148 *{ $pkg.PKG.$name } = $code;
  97         636  
711             }
712             }
713 92         223 return $self;
714             }
715              
716             sub overload {
717 516     516 1 574 my $self = shift;
718 516 100 66     2202 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
719 516 50       825 _debug("overload on $self->{name} : { ", join(', ', %$args), " }\n") if DEBUG;
720 516         2087 overload::OVERLOAD($self->{name}, %$args);
721 516         20649 return $self;
722             }
723              
724             sub as_text {
725 223     223 1 443 my ($self, $method) = @_;
726 223         583 $self->overload( '""' => $method, fallback => 1 );
727             }
728              
729             sub is_true {
730 219     219 1 401 my ($self, $arg) = @_;
731 219 50       794 my $method =
    50          
732             $arg eq FALSE ? \&FALSE : # allow 0/1 as shortcut
733             $arg eq TRUE ? \&TRUE :
734             $arg;
735 219         561 $self->overload( bool => $method, fallback => 1 );
736             }
737              
738              
739             #-----------------------------------------------------------------------
740             # misc methods
741             #-----------------------------------------------------------------------
742              
743             sub instance {
744 2     2 1 3 my $self = shift;
745 2         7 $self->{ name }->new(@_);
746             }
747              
748             sub loaded {
749             # "loaded" is defined as "has an entry in the symbol table"
750             # NOTE: this is incorrect - see comment in _autoload() wrt
751             # case-insensitive filesystems
752 3 100   3 1 3 keys %{ $_[0]->{ symbols } } ? 1 : 0;
  3         15  
753             }
754              
755             sub load {
756 120     120 1 159 my $self = shift;
757 120 50       250 _autoload($self->{ name }) || return;
758 98         325 return $self;
759             }
760              
761             sub maybe_load {
762 54     54 1 79 my $self = shift;
763 54   66     73 return eval { $self->load } || do {
764             _debug("maybe_load($self) caught error: $@\n") if DEBUG;
765             # Don't confuse "Can't locate Missing/Module/Used/In/Your/Module.pm"
766             # messages with "Can't locate Your/Module.pm". The former is an
767             # error that should be reported, the latter isn't. We convert the
768             # class name to a regex that matches any non-word directory separators
769             # e.g. Your::Module => Your\W+Module
770             my $name = join(
771             "\\W+",
772             map { quotemeta $_ }
773             split('::', $self->{ name })
774             );
775             _debug("checking to see if we couldn't locate $name\n") if DEBUG;
776             croak $@ if $@ && $@ !~ /^Can't locate $name.*? in \@INC/;
777             0;
778             }
779             }
780              
781              
782             #-----------------------------------------------------------------------
783             # methods for building Badger::Class subclasses
784             #-----------------------------------------------------------------------
785              
786             sub uber {
787 31     31 1 84 my ($self, $base) = @_;
788 31         60 my $pkg = $self->{ name };
789 31         105 $self->base($base);
790 31         175 $pkg->UBER;
791 31         71 return $self;
792             }
793              
794             sub hooks {
795 31     31 1 64 my $self = shift;
796 31 50       115 my $args = @_ == 1 ? shift : { @_ };
797 31         152 my $hooks = $self->var_default( HOOKS => { } );
798              
799             # split string into list ref
800 31 100       324 $args = [ split(DELIMITER, $args) ]
801             unless ref $args;
802              
803             # map list ref to hash ref
804             $args = {
805 31 100       171 map { $_ => $_ }
  99         226  
806             @$args
807             } if ref $args eq ARRAY;
808              
809 31 50       135 croak("Invalid hooks specified: $args")
810             unless ref $args eq HASH;
811              
812 31 50       104 _debug("merging $self->{ name } hooks: ", join(', ', keys %$args), "\n") if DEBUG;
813              
814 31         170 @$hooks{ keys %$args } = values %$args;
815              
816 31         109 return $self;
817             }
818              
819              
820             #-----------------------------------------------------------------------
821             # autoload($module)
822             #
823             # Helper subroutine to autoload a module.
824             #-----------------------------------------------------------------------
825              
826             sub _autoload {
827 6390     6390   7550 my $class = shift;
828 70     70   477 no strict REFS;
  70         142  
  70         2510  
829 70     70   385 no warnings ONCE;
  70         132  
  70         18595  
830 6390         5908 my $symbols = \%{"${class}::"};
  6390         15327  
831              
832 6390 100 100     6725 unless (
833 6390         40137 defined ${ $class.PKG.LOADED }
834 105081         120111 || scalar(grep { ! /::$/ } keys %$symbols) > 1 # any symbols defined other than import / sub-namespaces
835             ) {
836 649 50       1271 _debug("autoloading $class\n") if DEBUG;
837 649         2503 local $SIG{__DIE__};
838 70     70   26651 eval "use $class";
  70     70   185  
  70     70   959  
  70     70   33934  
  70     70   204  
  70     70   1021  
  70     68   30789  
  70     44   194  
  70     33   520  
  70     24   28667  
  70         194  
  70         471  
  70         35411  
  70         211  
  70         493  
  70         26032  
  70         178  
  70         1065  
  68         29184  
  68         293  
  68         687  
  44         17975  
  44         10155  
  44         659  
  33         12382  
  32         1993  
  32         410  
  24         9631  
  23         89  
  23         252  
  649         41487  
839 649 100       4736 croak $@ if $@;
840              
841             # Problem here is that case-insensitive filesystems could load the
842             # wrong module. We could check the symbol table, but it will always
843             # have an 'import' entry because 'use' attempts to call import().
844             # So we assume a successful module load requires there to be a symbol
845             # table with entries other than a single 'import'
846             # [later] Oh blimey, it's worse than that. There may be other
847             # sub-namespaces.
848             return 0
849 36999         42246 if scalar(grep { ! /::$/ } keys %$symbols) == 1
850 627 0 33     5577 && exists $symbols->{ import };
851              
852 627   100     1703 ${ $class.PKG.LOADED } ||= 1;
  627         4125  
853             }
854              
855 6368         31829 return $class;
856             }
857              
858             sub _debug {
859 0     0     print STDERR @_;
860             }
861              
862              
863             1;
864              
865             __END__