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     8143   10990 use strict;
  87         290  
  87         2264  
17 81     81   4929 use warnings;
  80         1151  
  80         1796  
18 77     77   3327 use Carp;
  77         204  
  77         4647  
19 75     75   2287 use base 'Badger::Exporter';
  74         210  
  74         36379  
20             use constant {
21 72         45343 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   2047 };
  72         1743  
40             use Badger::Constants
41 73     73   28639 'DELIMITER SCALAR ARRAY HASH CODE PKG REFS ONCE TRUE FALSE LOADED';
  70         142  
  70         2018  
42             use overload
43 70         455 '""' => 'name',
44 73     73   88992 fallback => 1;
  70         72798  
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   24414 *DEBUG = sub() { $DEBUG };
  28578     28578   48993  
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 6473 my ($class, $package, @args) = @_;
107 70     72   517 no strict REFS;
  72         788  
  70         2744  
108 70     72   408 no warnings ONCE;
  72         468  
  70         39636  
109 1502   100     1927 ${ $package.PKG.LOADED } ||= 1; # add $BADGER_LOADED to mark our scent
  1502         12356  
110 1502         5445 $class->SUPER::export($package, @args);
111             }
112              
113              
114             sub _export_hook {
115 8452     8452   15354 my ($class, $target, $key, $symbols) = @_;
116              
117 8452 50       14005 croak sprintf(NO_VALUE, $key)
118             unless @$symbols;
119              
120 8452         13665 class($target, $class)->$key(shift @$symbols);
121             }
122              
123              
124             sub _export_fail {
125 76     76   232 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     169 my $hook = class($class)->hash_value( HOOKS => $key ) || return;
130              
131 76 50       223 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         184 class($target, $class)->$hook(shift @$symbols);
139             }
140              
141              
142             sub _debug_hook {
143 1182     1182   2303 my ($class, $target, $key, $debug) = @_;
144 1182 50       3877 $debug = { default => $debug }
145             unless ref $debug eq HASH;
146 1182         4596 _autoload($class->DEBUGGER)->export($target, %$debug);
147             }
148              
149             sub _dumps_hook {
150 140     140   482 my ($class, $target, $key, $dumps) = @_;
151 140         510 _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 1294 @_ ? (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 356 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     566 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         167 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 12900 100   12900   24776 $class = @_ ? shift : (caller())[0];
204 12900   66     30029 $class = ref $class || $class;
205             return @_
206             ? $METACLASSES->{ $_[0] }->{ $class } ||= $_[0]->new($class)
207 12900 100 66     51351 : $CLASSES->{ $class } ||= $pkg->new($class);
      66        
208 101         425 };
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   9 $class = shift || (caller())[0];
217 2         6 $class_sub->($class)->heritage;
218 101         354 };
219              
220 70     71   541 no strict REFS;
  71         276  
  70         2753  
221 70     71   384 no warnings 'redefine';
  71         302  
  70         23383  
222 101         198 *{ $pkg.PKG.'CLASS' } = \&CLASS;
  101         501  
223 101         175 *{ $pkg.PKG.'class' } = $class_sub;
  101         342  
224 101         168 *{ $pkg.PKG.'bclass' } = $class_sub; # plan B
  101         424  
225 101         166 *{ $pkg.PKG.'classes' } = $classes_sub;
  101         459  
226 101         197 *{ $pkg.PKG.'_autoload' } = \&_autoload;
  101         313  
227              
228 101         810 $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 2405     2405   3658 my $self = shift;
247 2405         8478 _autoload($self->$module)->$method($self->{ name }, @_);
248 2405         4921 return $self;
249             };
250             }
251             keys %$DELEGATES
252             );
253              
254              
255             #-----------------------------------------------------------------------
256             # constructor method
257             #-----------------------------------------------------------------------
258              
259             sub new {
260 1711     1711 1 3149 my ($class, $package) = @_;
261 1711   33     4223 $package = ref $package || $package;
262 70     71   665 no strict 'refs';
  71         487  
  70         39503  
263             bless {
264             name => $package,
265 1711         2328 symbols => \%{"${package}::"},
  1711         36783  
266             }, $class;
267             }
268              
269             sub id {
270 54     54 1 101 my $self = shift;
271             return @_
272             ? $self->{ id } = shift
273 54 50 66     284 : $self->{ id } ||= do {
274 35         84 my $pkg = $self->{ name };
275 35         167 my $base = $self->base_id; # base to remove, e.g. Badger
276 35 100       110 if ($base eq $pkg) {
277 1 50       10 $pkg = $1 if $pkg =~ /(\w+)$/; # Badger - Badger --> Badger
278             } else {
279 34         452 $pkg =~ s/^${base}:://; # Badger::X::Y - Badger --> X::Y
280             }
281 35         151 $pkg =~ s/::/./g; # X::Y --> X.Y
282 35         367 lc $pkg; # X.Y --> x.y
283             };
284             }
285              
286              
287             #-----------------------------------------------------------------------
288             # methods to access symbol table
289             #-----------------------------------------------------------------------
290              
291             *pkg = \&name;
292 50467     50467 1 139836 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 1837 my ($self, $symbol, $ref) = @_;
306 70     70   519 no strict REFS;
  70         203  
  70         2476  
307 70     70   421 no warnings ONCE;
  70         487  
  70         6490  
308 930         1092 *{ $self->{ name }.PKG.$symbol } = $ref;
  930         5724  
309             }
310              
311              
312             #-----------------------------------------------------------------------
313             # methods for accessing class variables that DTRT in subclasses
314             #-----------------------------------------------------------------------
315              
316             sub var {
317 230     230 1 405 my $self = shift;
318 230         365 my $name = shift;
319 70     70   547 no strict REFS;
  70         117  
  70         2551  
320 70     70   382 no warnings ONCE;
  70         176  
  70         7715  
321              
322             # _debug("Looking for $self->{ name }", PKG, $name, " args: ", scalar(@_), " => ", join(', ', @_), "\n");
323             return @_
324 105         654 ? (${ $self->{name}.PKG.$name } = shift)
325 230 100       664 : ${ $self->{name}.PKG.$name };
  125         574  
326             }
327              
328             sub var_default {
329 44     44 1 151 my ($self, $name, $default) = @_;
330 70     70   461 no strict REFS;
  70         129  
  70         2388  
331 70     70   367 no warnings ONCE;
  70         119  
  70         6470  
332              
333 44   66     86 return ${ $self->{name}.PKG.$name }
  44         504  
334             ||= $default;
335             }
336              
337             sub any_var {
338 266     266 1 467 my $self = shift;
339 266         391 my $name = shift;
340 70     70   467 no strict REFS;
  70         135  
  70         13129  
341              
342             # remove any leading '$'
343 266         486 $name =~ s/^\$//;
344              
345 266         534 foreach my $pkg ($self->heritage) {
346 596 50       960 _debug("looking for $name in $pkg\n") if DEBUG;
347 596 100       713 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  180         357  
  596         958  
348             }
349              
350 86         562 return undef;
351             }
352              
353             sub any_var_in {
354 120     120 1 244 my $self = shift;
355 120 100       340 my $names = @_ == 1 ? shift : [@_];
356 120         199 my ($pkg, $name);
357 70     70   480 no strict REFS;
  70         145  
  70         15734  
358              
359 120 100       618 $names = [ split DELIMITER, $names ]
360             unless ref $names eq ARRAY;
361              
362             # remove any leading '$'
363 120         267 $names = [ map { s/^\$//; $_ } @$names ];
  156         298  
  156         415  
364              
365 120         476 foreach $pkg ($self->heritage) {
366 257         419 foreach $name (@$names) {
367 392 50       582 _debug("looking for $name in $pkg\n") if DEBUG;
368 392 100       445 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  86         140  
  392         631  
369             }
370             }
371              
372 34         158 return undef;
373             }
374              
375             sub all_vars {
376 2183     2183 1 3228 my ($self, $name) = @_;
377 2183         3003 my $pkg = $self->{ name };
378 2183         2656 my ($value, @values);
379 70     70   568 no strict REFS;
  70         141  
  70         2655  
380 70     70   385 no warnings ONCE;
  70         117  
  70         42775  
381              
382             # remove any leading '$'
383 2183         2776 $name =~ s/^\$//;
384              
385             # _debug("all_vars() caller: ", join(', ', caller()), "\n");
386              
387 2183         3639 foreach my $pkg ($self->heritage) {
388 6723 50 0     8741 _debug("looking for $name in ", $pkg || "UNDEF", "\n") if DEBUG;
389             push(@values, $value)
390 6723 100       6827 if defined ($value = ${ $pkg.PKG.$name });
  6723         9405  
391 6723 50 33     8919 _debug("got: $value\n") if DEBUG && $value;
392             }
393              
394 2183 100       5840 return wantarray ? @values : \@values;
395              
396             }
397              
398             sub list_vars {
399 155     155 1 310 my $self = shift; # must remove these from @_ here
400 155         238 my $name = shift;
401 155         346 my $vars = $self->all_vars($name);
402 155         289 my (@merged, $list);
403              
404             # remove any leading '$'
405 155         645 $name =~ s/^\$//;
406              
407 155         313 foreach $list (@_, @$vars) { # use whatever is left in @_ here
408 159 100       367 next unless defined $list;
409 87 100       242 if (ref $list eq ARRAY) {
410 66 50       191 next unless @$list;
411 66         194 push(@merged, @$list);
412             }
413             else {
414 21         44 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       782 return wantarray ? @merged : \@merged;
425              
426             }
427              
428             sub hash_vars {
429 75     75 1 130 my $self = shift; # must remove these from @_ here
430 75         106 my $name = shift;
431 75         164 my $vars = $self->all_vars($name);
432 75         148 my (%merged, $hash);
433              
434             # remove any leading '$'
435 75         176 $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 75         160 foreach $hash ( reverse(@$vars), @_ ) {
440 143 100       363 next unless defined $hash;
441 47 50       180 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 47         355 @merged{ keys %$hash } = values %$hash;
446             }
447              
448 75         250 return \%merged;
449             }
450              
451             sub hash_value {
452 1951     1951 1 3659 my ($self, $name, $item, $default) = @_;
453              
454             # remove any leading '$'
455 1951         3193 $name =~ s/^\$//;
456              
457             # _debug("hash_value() caller: ", join(', ', caller()), "\n");
458              
459 1951         3739 foreach my $hash ($self->all_vars($name)) {
460 1956 50       4129 next unless ref $hash eq HASH;
461             return $hash->{ $item }
462 1956 100       7439 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 932 my $self = shift;
475 721   33     1385 my $class = ref $self || $self;
476 721         1030 my $pkg = $self->{ name };
477 721   66     1859 my $parents = $self->{ parents } ||= do {
478 70     70   541 no strict REFS;
  70         137  
  70         21104  
479              
480             # make sure the module is loaded before we go looking at its @ISA
481 480         1212 _autoload($pkg);
482             [
483 408         750 map { class($_) } # parents are immediate
484 480         640 @{ $pkg.PKG.ISA } # superclasses defined in @ISA
  480         1823  
485             ];
486             };
487              
488             return wantarray
489 721 50       2425 ? @$parents
490             : $parents;
491             }
492              
493             sub heritage {
494 2598     2598 1 3096 my $self = shift;
495 2598   66     5123 my $heritage = $self->{ heritage } ||= do {
496 221         545 my @pending = ($self);
497 221         393 my (%seen, $item, @order);
498 221         612 while (@pending) {
499 720 50       1629 next unless defined ($item = pop @pending);
500 720         1136 unshift(@order, $item);
501 720         847 push(@pending, reverse @{ $item->parents });
  720         2293  
502             }
503 221         579 [ reverse grep { ! $seen{$_}++ } @order ];
  720         1156  
504             };
505             return wantarray
506 2598 50       6697 ? @$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 2958 my $self = shift;
517 2127 50       3948 my $bases = @_ == 1 ? shift : [ @_ ];
518 2127         2850 my $pkg = $self->{ name };
519              
520 2127 50       16462 $bases = [ split(DELIMITER, $bases) ]
521             unless ref $bases eq ARRAY;
522              
523             # add each of $bases to @ISA and autoload it
524 2127         4618 foreach my $base (@$bases) {
525 70     70   475 no strict REFS;
  70         123  
  70         28207  
526 2312 100       20556 next if $pkg->isa($base);
527 2061 50       4090 _debug("Adding $pkg base class $base\n") if DEBUG;
528 2061         2588 push @{ $pkg.PKG.ISA }, $base;
  2061         26739  
529 2061         6797 _autoload($base);
530             }
531 2127         5041 return $self;
532             }
533              
534             sub mixin {
535 3     3 1 5 my $self = shift;
536 3 50       8 my $mixins = @_ == 1 ? shift : [ @_ ];
537              
538 3 50       22 $mixins = [ split(DELIMITER, $mixins) ]
539             unless ref $mixins eq ARRAY;
540              
541 3         11 foreach my $name (@$mixins) {
542             # $name = $target . $name if $name =~ /^::/;
543             # $self->debug("mixing $name into $self\n") if $DEBUG;
544 3         7 _autoload($name)->mixin($self->{ name });
545             }
546              
547 3         7 return $self;
548             }
549              
550             sub mixins {
551 3     3 1 6 my $self = shift;
552 3         7 $self->base(MIXIN);
553 3         16 $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 2521 my ($self, $version) = @_;
573 1384         2178 my $pkg = $self->{ name };
574 70     70   529 no strict 'refs';
  70         152  
  70         20540  
575 1384 50       2323 _debug("Defining $pkg version $version\n") if DEBUG;
576              
577             # define $VERSION and VERSION()
578 1384         5086 *{ $pkg.PKG.VERSION } = \$version
579 1384         8431 unless defined ${ $pkg.PKG.VERSION }
580 1384 50 33     1749 && ${ $pkg.PKG.VERSION };
  0         0  
581 1384     6   4294 *{ $pkg.PKG.VERSION } = sub() { $version }
  6         30  
582 1384 50       1862 unless defined &{ $pkg.PKG.VERSION }; # CHECK THIS - was 'version'
  1384         7578  
583              
584 1384         3482 return $self;
585             }
586              
587             sub constant {
588 797     797 1 1237 my $self = shift;
589 797 100       1668 my $constants = @_ == 1 ? shift : { @_ };
590 797         1190 my $pkg = $self->{ name };
591              
592             # split string into pairs of assignments, e.g. "foo=bar, baz=bam"
593             $constants = {
594 797 50       1891 map { split /\s*=>?\s*/ }
  0         0  
595             split(DELIMITER, $constants)
596             } unless ref $constants eq HASH;
597              
598              
599 797         3255 while (my ($name, $value) = each %$constants) {
600 70     70   518 no strict REFS;
  70         162  
  70         13340  
601 2449         3257 my $v = $value; # new lexical variable to bind in closure
602 2449 50       3519 _debug("Defining $pkg constant $name => $value\n") if DEBUG;
603 2449     0   11814 *{ $pkg.PKG.$name } = sub() { $value };
  2449         14552  
  0         0  
604             }
605 797         1862 return $self;
606             }
607              
608             sub words {
609 493     493 1 1154 my $self = shift;
610 493 50       1149 my $words = @_ == 1 ? shift : [ @_ ];
611 493         1066 my $pkg = $self->{ name };
612              
613 493 50       4239 $words = [ split(DELIMITER, $words) ]
614             unless ref $words eq ARRAY;
615              
616 493         1253 foreach (@$words) {
617 70     70   480 no strict REFS;
  70         115  
  70         18446  
618 1287         1914 my $word = $_; # new lexical variable to bind in closure
619 1287 50       2270 _debug("Defining $pkg word $word\n") if DEBUG;
620 1287     0   6891 *{ $pkg.PKG.$word } = sub() { $word };
  1287         6467  
  0         0  
621             }
622 493         1383 return $self;
623             }
624              
625             sub exports {
626 695     695 1 1067 my $self = shift;
627 695         1072 my $pkg = $self->{ name };
628 695         1830 $self->base(EXPORTER);
629 695         3867 $pkg->exports(@_);
630 695         1488 return $self;
631             }
632              
633             sub throws {
634 2     2 1 9 my ($self, $throws) = @_;
635 2         9 $self->import_symbol(THROWS, \$throws);
636 2         5 return $self;
637             }
638              
639             sub messages {
640 638     638 1 977 my $self = shift;
641 638 100 66     2605 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
642 638         1000 my $pkg = $self->{ name };
643 70     70   463 no strict REFS;
  70         121  
  70         2432  
644 70     70   430 no warnings ONCE;
  70         169  
  70         15424  
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         854 my $messages = ${ $pkg.PKG.MESSAGES };
  638         2808  
649              
650 638 100       1229 if ($messages) {
651 1 50       3 _debug("merging $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
652 1         7 @$messages{ keys %$args } = values %$args;
653             }
654             else {
655 637 50       1100 _debug("adding $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
656 637         958 ${ $pkg.PKG.MESSAGES } = $messages = $args;
  637         1564  
657             }
658              
659 638         1332 return $self;
660             }
661              
662             sub method {
663 25     25 1 64 my $self = shift;
664 25         45 my $name = shift;
665 70     70   490 no strict REFS;
  70         147  
  70         2433  
666 70     70   456 no warnings 'redefine';
  70         185  
  70         14080  
667              
668             # method($name) can be used to fetch a method/sub
669 25 100       101 return $self->{ name }->can($name)
670             unless @_;
671              
672             # method($name => $code) or $method($name => $value) to define method
673 21         36 my $code = shift;
674 21 50       62 _debug("defining method: $self\::$name => $code\n") if DEBUG;
675              
676 21         124 *{ $self->{name}.PKG.$name } = ref $code eq CODE
677             ? $code
678 21 100   3   83 : sub { $code }; # constant method returns value
  3         8  
679              
680 21         62 return $self;
681             }
682              
683             sub methods {
684 713     713 1 1190 my $self = shift;
685 713 100 66     5193 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
686 713         1436 my $pkg = $self->{ name };
687 70     70   484 no strict REFS;
  70         156  
  70         2585  
688 70     70   413 no warnings 'redefine';
  70         112  
  70         13460  
689              
690 713         3759 while (my ($name, $code) = each %$args) {
691 4967 50       7543 _debug("defining method: $self\::$name => $code\n") if DEBUG;
692 4967         24458 *{ $pkg.PKG.$name }
693 4967 100   1   7813 = ref $code eq CODE ? $code : sub { $code };
  1         4  
694             }
695 713         2379 return $self;
696             }
697              
698             sub alias {
699 92     92 1 226 my $self = shift;
700 92 100 66     656 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
701 92         236 my $pkg = $self->{ name };
702 70     70   469 no strict REFS;
  70         141  
  70         65556  
703              
704 92         490 while (my ($names, $code) = each %$args) {
705 97 50       281 _debug("defining alias: $self\::$names => $code\n") if DEBUG;
706 97 100 33     347 $code = $self->method($code)
707             || croak "Invalid method specified for '$names' alias: $code"
708             unless ref $code eq CODE;
709 97         520 foreach my $name (split(DELIMITER, $names)) {
710 97         161 *{ $pkg.PKG.$name } = $code;
  97         772  
711             }
712             }
713 92         291 return $self;
714             }
715              
716             sub overload {
717 516     516 1 768 my $self = shift;
718 516 100 66     2542 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
719 516 50       928 _debug("overload on $self->{name} : { ", join(', ', %$args), " }\n") if DEBUG;
720 516         2306 overload::OVERLOAD($self->{name}, %$args);
721 516         24444 return $self;
722             }
723              
724             sub as_text {
725 223     223 1 544 my ($self, $method) = @_;
726 223         618 $self->overload( '""' => $method, fallback => 1 );
727             }
728              
729             sub is_true {
730 219     219 1 558 my ($self, $arg) = @_;
731 219 50       989 my $method =
    50          
732             $arg eq FALSE ? \&FALSE : # allow 0/1 as shortcut
733             $arg eq TRUE ? \&TRUE :
734             $arg;
735 219         591 $self->overload( bool => $method, fallback => 1 );
736             }
737              
738              
739             #-----------------------------------------------------------------------
740             # misc methods
741             #-----------------------------------------------------------------------
742              
743             sub instance {
744 2     2 1 11 my $self = shift;
745 2         13 $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 14 keys %{ $_[0]->{ symbols } } ? 1 : 0;
  3         19  
753             }
754              
755             sub load {
756 120     120 1 208 my $self = shift;
757 120 50       281 _autoload($self->{ name }) || return;
758 98         387 return $self;
759             }
760              
761             sub maybe_load {
762 54     54 1 107 my $self = shift;
763 54   66     91 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 140 my ($self, $base) = @_;
788 31         107 my $pkg = $self->{ name };
789 31         120 $self->base($base);
790 31         299 $pkg->UBER;
791 31         96 return $self;
792             }
793              
794             sub hooks {
795 31     31 1 126 my $self = shift;
796 31 50       147 my $args = @_ == 1 ? shift : { @_ };
797 31         199 my $hooks = $self->var_default( HOOKS => { } );
798              
799             # split string into list ref
800 31 100       366 $args = [ split(DELIMITER, $args) ]
801             unless ref $args;
802              
803             # map list ref to hash ref
804             $args = {
805 31 100       181 map { $_ => $_ }
  99         312  
806             @$args
807             } if ref $args eq ARRAY;
808              
809 31 50       198 croak("Invalid hooks specified: $args")
810             unless ref $args eq HASH;
811              
812 31 50       152 _debug("merging $self->{ name } hooks: ", join(', ', keys %$args), "\n") if DEBUG;
813              
814 31         214 @$hooks{ keys %$args } = values %$args;
815              
816 31         145 return $self;
817             }
818              
819              
820             #-----------------------------------------------------------------------
821             # autoload($module)
822             #
823             # Helper subroutine to autoload a module.
824             #-----------------------------------------------------------------------
825              
826             sub _autoload {
827 6391     6391   8756 my $class = shift;
828 70     70   521 no strict REFS;
  70         146  
  70         2758  
829 70     70   422 no warnings ONCE;
  70         144  
  70         21315  
830 6391         6978 my $symbols = \%{"${class}::"};
  6391         17661  
831              
832 6391 100 100     8015 unless (
833 6391         44098 defined ${ $class.PKG.LOADED }
834 105081         146487 || scalar(grep { ! /::$/ } keys %$symbols) > 1 # any symbols defined other than import / sub-namespaces
835             ) {
836 649 50       1541 _debug("autoloading $class\n") if DEBUG;
837 649         2930 local $SIG{__DIE__};
838 70     70   30123 eval "use $class";
  70     70   243  
  70     70   1087  
  70     70   40400  
  70     70   242  
  70     70   1186  
  70     68   35935  
  70     44   229  
  70     33   540  
  70     24   33767  
  70         214  
  70         535  
  70         39941  
  70         257  
  70         541  
  70         30723  
  70         229  
  70         1173  
  68         34187  
  68         226  
  68         551  
  44         20716  
  44         12029  
  44         731  
  33         14744  
  32         2601  
  32         502  
  24         10895  
  23         119  
  23         243  
  649         45732  
839 649 100       5496 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         51431 if scalar(grep { ! /::$/ } keys %$symbols) == 1
850 627 0 33     6297 && exists $symbols->{ import };
851              
852 627   100     1970 ${ $class.PKG.LOADED } ||= 1;
  627         4338  
853             }
854              
855 6369         36540 return $class;
856             }
857              
858             sub _debug {
859 0     0     print STDERR @_;
860             }
861              
862              
863             1;
864              
865             __END__