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     8341   10375 use strict;
  87         201  
  87         2219  
17 81     81   4759 use warnings;
  80         1167  
  80         1791  
18 77     77   3304 use Carp;
  77         219  
  77         4484  
19 75     75   2180 use base 'Badger::Exporter';
  74         186  
  74         34744  
20             use constant {
21 72         43838 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   1875 };
  72         143  
40             use Badger::Constants
41 73     73   28200 'DELIMITER SCALAR ARRAY HASH CODE PKG REFS ONCE TRUE FALSE LOADED';
  70         1735  
  70         1973  
42             use overload
43 70         448 '""' => 'name',
44 73     73   86609 fallback => 1;
  70         71140  
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   23829 *DEBUG = sub() { $DEBUG };
  28578     28578   47343  
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 6294 my ($class, $package, @args) = @_;
107 70     72   498 no strict REFS;
  72         688  
  70         2614  
108 70     72   374 no warnings ONCE;
  72         467  
  70         37789  
109 1502   100     1932 ${ $package.PKG.LOADED } ||= 1; # add $BADGER_LOADED to mark our scent
  1502         12137  
110 1502         5375 $class->SUPER::export($package, @args);
111             }
112              
113              
114             sub _export_hook {
115 8452     8452   15138 my ($class, $target, $key, $symbols) = @_;
116              
117 8452 50       13496 croak sprintf(NO_VALUE, $key)
118             unless @$symbols;
119              
120 8452         17647 class($target, $class)->$key(shift @$symbols);
121             }
122              
123              
124             sub _export_fail {
125 76     76   230 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     158 my $hook = class($class)->hash_value( HOOKS => $key ) || return;
130              
131 76 50       194 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         155 class($target, $class)->$hook(shift @$symbols);
139             }
140              
141              
142             sub _debug_hook {
143 1182     1182   2388 my ($class, $target, $key, $debug) = @_;
144 1182 50       3758 $debug = { default => $debug }
145             unless ref $debug eq HASH;
146 1182         4450 _autoload($class->DEBUGGER)->export($target, %$debug);
147             }
148              
149             sub _dumps_hook {
150 140     140   399 my ($class, $target, $key, $dumps) = @_;
151 140         534 _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 1180 @_ ? (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 328 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     560 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         152 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   24496 $class = @_ ? shift : (caller())[0];
204 12900   66     29330 $class = ref $class || $class;
205             return @_
206             ? $METACLASSES->{ $_[0] }->{ $class } ||= $_[0]->new($class)
207 12900 100 66     50168 : $CLASSES->{ $class } ||= $pkg->new($class);
      66        
208 101         419 };
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   7 $class = shift || (caller())[0];
217 2         4 $class_sub->($class)->heritage;
218 101         315 };
219              
220 70     71   496 no strict REFS;
  71         290  
  70         2434  
221 70     71   390 no warnings 'redefine';
  71         325  
  70         22759  
222 101         188 *{ $pkg.PKG.'CLASS' } = \&CLASS;
  101         471  
223 101         177 *{ $pkg.PKG.'class' } = $class_sub;
  101         336  
224 101         154 *{ $pkg.PKG.'bclass' } = $class_sub; # plan B
  101         378  
225 101         139 *{ $pkg.PKG.'classes' } = $classes_sub;
  101         450  
226 101         183 *{ $pkg.PKG.'_autoload' } = \&_autoload;
  101         314  
227              
228 101         764 $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   3345 my $self = shift;
247 2405         7932 _autoload($self->$module)->$method($self->{ name }, @_);
248 2405         4732 return $self;
249             };
250             }
251             keys %$DELEGATES
252             );
253              
254              
255             #-----------------------------------------------------------------------
256             # constructor method
257             #-----------------------------------------------------------------------
258              
259             sub new {
260 1711     1711 1 3200 my ($class, $package) = @_;
261 1711   33     4116 $package = ref $package || $package;
262 70     71   656 no strict 'refs';
  71         487  
  70         39384  
263             bless {
264             name => $package,
265 1711         2240 symbols => \%{"${package}::"},
  1711         35555  
266             }, $class;
267             }
268              
269             sub id {
270 54     54 1 115 my $self = shift;
271             return @_
272             ? $self->{ id } = shift
273 54 50 66     257 : $self->{ id } ||= do {
274 35         67 my $pkg = $self->{ name };
275 35         114 my $base = $self->base_id; # base to remove, e.g. Badger
276 35 100       107 if ($base eq $pkg) {
277 1 50       9 $pkg = $1 if $pkg =~ /(\w+)$/; # Badger - Badger --> Badger
278             } else {
279 34         719 $pkg =~ s/^${base}:://; # Badger::X::Y - Badger --> X::Y
280             }
281 35         137 $pkg =~ s/::/./g; # X::Y --> X.Y
282 35         363 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 135719 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 1830 my ($self, $symbol, $ref) = @_;
306 70     70   498 no strict REFS;
  70         181  
  70         2519  
307 70     70   415 no warnings ONCE;
  70         451  
  70         6335  
308 930         1056 *{ $self->{ name }.PKG.$symbol } = $ref;
  930         5599  
309             }
310              
311              
312             #-----------------------------------------------------------------------
313             # methods for accessing class variables that DTRT in subclasses
314             #-----------------------------------------------------------------------
315              
316             sub var {
317 230     230 1 401 my $self = shift;
318 230         344 my $name = shift;
319 70     70   483 no strict REFS;
  70         173  
  70         2422  
320 70     70   376 no warnings ONCE;
  70         190  
  70         7578  
321              
322             # _debug("Looking for $self->{ name }", PKG, $name, " args: ", scalar(@_), " => ", join(', ', @_), "\n");
323             return @_
324 105         619 ? (${ $self->{name}.PKG.$name } = shift)
325 230 100       530 : ${ $self->{name}.PKG.$name };
  125         503  
326             }
327              
328             sub var_default {
329 44     44 1 130 my ($self, $name, $default) = @_;
330 70     70   449 no strict REFS;
  70         130  
  70         2337  
331 70     70   365 no warnings ONCE;
  70         121  
  70         6433  
332              
333 44   66     94 return ${ $self->{name}.PKG.$name }
  44         471  
334             ||= $default;
335             }
336              
337             sub any_var {
338 266     266 1 399 my $self = shift;
339 266         323 my $name = shift;
340 70     70   421 no strict REFS;
  70         149  
  70         12914  
341              
342             # remove any leading '$'
343 266         502 $name =~ s/^\$//;
344              
345 266         501 foreach my $pkg ($self->heritage) {
346 596 50       964 _debug("looking for $name in $pkg\n") if DEBUG;
347 596 100       682 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  180         329  
  596         1012  
348             }
349              
350 86         524 return undef;
351             }
352              
353             sub any_var_in {
354 120     120 1 202 my $self = shift;
355 120 100       313 my $names = @_ == 1 ? shift : [@_];
356 120         189 my ($pkg, $name);
357 70     70   487 no strict REFS;
  70         103  
  70         15406  
358              
359 120 100       608 $names = [ split DELIMITER, $names ]
360             unless ref $names eq ARRAY;
361              
362             # remove any leading '$'
363 120         258 $names = [ map { s/^\$//; $_ } @$names ];
  156         264  
  156         387  
364              
365 120         304 foreach $pkg ($self->heritage) {
366 257         399 foreach $name (@$names) {
367 392 50       580 _debug("looking for $name in $pkg\n") if DEBUG;
368 392 100       426 return ${ $pkg.PKG.$name } if defined ${ $pkg.PKG.$name };
  86         132  
  392         583  
369             }
370             }
371              
372 34         142 return undef;
373             }
374              
375             sub all_vars {
376 2183     2183 1 3073 my ($self, $name) = @_;
377 2183         2890 my $pkg = $self->{ name };
378 2183         2588 my ($value, @values);
379 70     70   478 no strict REFS;
  70         138  
  70         2518  
380 70     70   359 no warnings ONCE;
  70         170  
  70         41631  
381              
382             # remove any leading '$'
383 2183         2643 $name =~ s/^\$//;
384              
385             # _debug("all_vars() caller: ", join(', ', caller()), "\n");
386              
387 2183         3527 foreach my $pkg ($self->heritage) {
388 6723 50 0     8514 _debug("looking for $name in ", $pkg || "UNDEF", "\n") if DEBUG;
389             push(@values, $value)
390 6723 100       6691 if defined ($value = ${ $pkg.PKG.$name });
  6723         9317  
391 6723 50 33     8629 _debug("got: $value\n") if DEBUG && $value;
392             }
393              
394 2183 100       5485 return wantarray ? @values : \@values;
395              
396             }
397              
398             sub list_vars {
399 155     155 1 257 my $self = shift; # must remove these from @_ here
400 155         208 my $name = shift;
401 155         332 my $vars = $self->all_vars($name);
402 155         251 my (@merged, $list);
403              
404             # remove any leading '$'
405 155         254 $name =~ s/^\$//;
406              
407 155         330 foreach $list (@_, @$vars) { # use whatever is left in @_ here
408 159 100       343 next unless defined $list;
409 87 100       270 if (ref $list eq ARRAY) {
410 66 50       155 next unless @$list;
411 66         175 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       730 return wantarray ? @merged : \@merged;
425              
426             }
427              
428             sub hash_vars {
429 75     75 1 125 my $self = shift; # must remove these from @_ here
430 75         99 my $name = shift;
431 75         159 my $vars = $self->all_vars($name);
432 75         128 my (%merged, $hash);
433              
434             # remove any leading '$'
435 75         142 $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         174 foreach $hash ( reverse(@$vars), @_ ) {
440 143 100       339 next unless defined $hash;
441 47 50       152 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         335 @merged{ keys %$hash } = values %$hash;
446             }
447              
448 75         264 return \%merged;
449             }
450              
451             sub hash_value {
452 1951     1951 1 3455 my ($self, $name, $item, $default) = @_;
453              
454             # remove any leading '$'
455 1951         3077 $name =~ s/^\$//;
456              
457             # _debug("hash_value() caller: ", join(', ', caller()), "\n");
458              
459 1951         3616 foreach my $hash ($self->all_vars($name)) {
460 1956 50       4136 next unless ref $hash eq HASH;
461             return $hash->{ $item }
462 1956 100       7190 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 853 my $self = shift;
475 721   33     1356 my $class = ref $self || $self;
476 721         1021 my $pkg = $self->{ name };
477 721   66     1777 my $parents = $self->{ parents } ||= do {
478 70     70   558 no strict REFS;
  70         167  
  70         20459  
479              
480             # make sure the module is loaded before we go looking at its @ISA
481 480         1190 _autoload($pkg);
482             [
483 408         727 map { class($_) } # parents are immediate
484 480         605 @{ $pkg.PKG.ISA } # superclasses defined in @ISA
  480         1658  
485             ];
486             };
487              
488             return wantarray
489 721 50       2323 ? @$parents
490             : $parents;
491             }
492              
493             sub heritage {
494 2598     2598 1 2996 my $self = shift;
495 2598   66     5035 my $heritage = $self->{ heritage } ||= do {
496 221         517 my @pending = ($self);
497 221         359 my (%seen, $item, @order);
498 221         633 while (@pending) {
499 720 50       1516 next unless defined ($item = pop @pending);
500 720         1167 unshift(@order, $item);
501 720         845 push(@pending, reverse @{ $item->parents });
  720         2137  
502             }
503 221         535 [ reverse grep { ! $seen{$_}++ } @order ];
  720         1091  
504             };
505             return wantarray
506 2598 50       6390 ? @$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 2792 my $self = shift;
517 2127 50       3982 my $bases = @_ == 1 ? shift : [ @_ ];
518 2127         2808 my $pkg = $self->{ name };
519              
520 2127 50       15928 $bases = [ split(DELIMITER, $bases) ]
521             unless ref $bases eq ARRAY;
522              
523             # add each of $bases to @ISA and autoload it
524 2127         4358 foreach my $base (@$bases) {
525 70     70   479 no strict REFS;
  70         105  
  70         27256  
526 2312 100       20051 next if $pkg->isa($base);
527 2061 50       4052 _debug("Adding $pkg base class $base\n") if DEBUG;
528 2061         2475 push @{ $pkg.PKG.ISA }, $base;
  2061         25844  
529 2061         6638 _autoload($base);
530             }
531 2127         4945 return $self;
532             }
533              
534             sub mixin {
535 3     3 1 4 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         7 foreach my $name (@$mixins) {
542             # $name = $target . $name if $name =~ /^::/;
543             # $self->debug("mixing $name into $self\n") if $DEBUG;
544 3         13 _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         6 $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 2466 my ($self, $version) = @_;
573 1384         2041 my $pkg = $self->{ name };
574 70     70   498 no strict 'refs';
  70         121  
  70         20133  
575 1384 50       2336 _debug("Defining $pkg version $version\n") if DEBUG;
576              
577             # define $VERSION and VERSION()
578 1384         4905 *{ $pkg.PKG.VERSION } = \$version
579 1384         8189 unless defined ${ $pkg.PKG.VERSION }
580 1384 50 33     1785 && ${ $pkg.PKG.VERSION };
  0         0  
581 1384     6   4423 *{ $pkg.PKG.VERSION } = sub() { $version }
  6         32  
582 1384 50       1806 unless defined &{ $pkg.PKG.VERSION }; # CHECK THIS - was 'version'
  1384         7958  
583              
584 1384         3396 return $self;
585             }
586              
587             sub constant {
588 797     797 1 1129 my $self = shift;
589 797 100       1642 my $constants = @_ == 1 ? shift : { @_ };
590 797         1243 my $pkg = $self->{ name };
591              
592             # split string into pairs of assignments, e.g. "foo=bar, baz=bam"
593             $constants = {
594 797 50       1810 map { split /\s*=>?\s*/ }
  0         0  
595             split(DELIMITER, $constants)
596             } unless ref $constants eq HASH;
597              
598              
599 797         3259 while (my ($name, $value) = each %$constants) {
600 70     70   519 no strict REFS;
  70         155  
  70         12975  
601 2449         3200 my $v = $value; # new lexical variable to bind in closure
602 2449 50       3412 _debug("Defining $pkg constant $name => $value\n") if DEBUG;
603 2449     0   11994 *{ $pkg.PKG.$name } = sub() { $value };
  2449         14495  
  0         0  
604             }
605 797         1806 return $self;
606             }
607              
608             sub words {
609 493     493 1 1134 my $self = shift;
610 493 50       1075 my $words = @_ == 1 ? shift : [ @_ ];
611 493         1026 my $pkg = $self->{ name };
612              
613 493 50       4030 $words = [ split(DELIMITER, $words) ]
614             unless ref $words eq ARRAY;
615              
616 493         1208 foreach (@$words) {
617 70     70   460 no strict REFS;
  70         106  
  70         17538  
618 1287         1883 my $word = $_; # new lexical variable to bind in closure
619 1287 50       2252 _debug("Defining $pkg word $word\n") if DEBUG;
620 1287     0   6657 *{ $pkg.PKG.$word } = sub() { $word };
  1287         6672  
  0         0  
621             }
622 493         1397 return $self;
623             }
624              
625             sub exports {
626 695     695 1 1034 my $self = shift;
627 695         1002 my $pkg = $self->{ name };
628 695         1763 $self->base(EXPORTER);
629 695         3561 $pkg->exports(@_);
630 695         1377 return $self;
631             }
632              
633             sub throws {
634 2     2 1 19 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 936 my $self = shift;
641 638 100 66     2423 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
642 638         1017 my $pkg = $self->{ name };
643 70     70   490 no strict REFS;
  70         110  
  70         2352  
644 70     70   367 no warnings ONCE;
  70         135  
  70         14428  
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         745 my $messages = ${ $pkg.PKG.MESSAGES };
  638         2738  
649              
650 638 100       1248 if ($messages) {
651 1 50       3 _debug("merging $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
652 1         6 @$messages{ keys %$args } = values %$args;
653             }
654             else {
655 637 50       1218 _debug("adding $pkg messages: ", join(', ', keys %$args), "\n") if DEBUG;
656 637         937 ${ $pkg.PKG.MESSAGES } = $messages = $args;
  637         1413  
657             }
658              
659 638         1368 return $self;
660             }
661              
662             sub method {
663 25     25 1 63 my $self = shift;
664 25         42 my $name = shift;
665 70     70   456 no strict REFS;
  70         146  
  70         2396  
666 70     70   415 no warnings 'redefine';
  70         140  
  70         13817  
667              
668             # method($name) can be used to fetch a method/sub
669 25 100       109 return $self->{ name }->can($name)
670             unless @_;
671              
672             # method($name => $code) or $method($name => $value) to define method
673 21         32 my $code = shift;
674 21 50       44 _debug("defining method: $self\::$name => $code\n") if DEBUG;
675              
676 21         119 *{ $self->{name}.PKG.$name } = ref $code eq CODE
677             ? $code
678 21 100   3   76 : sub { $code }; # constant method returns value
  3         7  
679              
680 21         55 return $self;
681             }
682              
683             sub methods {
684 713     713 1 1172 my $self = shift;
685 713 100 66     5152 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
686 713         1482 my $pkg = $self->{ name };
687 70     70   486 no strict REFS;
  70         132  
  70         2391  
688 70     70   366 no warnings 'redefine';
  70         123  
  70         13993  
689              
690 713         3203 while (my ($name, $code) = each %$args) {
691 4967 50       7309 _debug("defining method: $self\::$name => $code\n") if DEBUG;
692 4967         24057 *{ $pkg.PKG.$name }
693 4967 100   1   7862 = ref $code eq CODE ? $code : sub { $code };
  1         5  
694             }
695 713         2349 return $self;
696             }
697              
698             sub alias {
699 92     92 1 205 my $self = shift;
700 92 100 66     676 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
701 92         253 my $pkg = $self->{ name };
702 70     70   463 no strict REFS;
  70         131  
  70         63385  
703              
704 92         479 while (my ($names, $code) = each %$args) {
705 97 50       272 _debug("defining alias: $self\::$names => $code\n") if DEBUG;
706 97 100 33     394 $code = $self->method($code)
707             || croak "Invalid method specified for '$names' alias: $code"
708             unless ref $code eq CODE;
709 97         553 foreach my $name (split(DELIMITER, $names)) {
710 97         165 *{ $pkg.PKG.$name } = $code;
  97         790  
711             }
712             }
713 92         287 return $self;
714             }
715              
716             sub overload {
717 516     516 1 643 my $self = shift;
718 516 100 66     2458 my $args = @_ && ref $_[0] eq HASH ? shift : { @_ };
719 516 50       966 _debug("overload on $self->{name} : { ", join(', ', %$args), " }\n") if DEBUG;
720 516         2265 overload::OVERLOAD($self->{name}, %$args);
721 516         23718 return $self;
722             }
723              
724             sub as_text {
725 223     223 1 517 my ($self, $method) = @_;
726 223         590 $self->overload( '""' => $method, fallback => 1 );
727             }
728              
729             sub is_true {
730 219     219 1 472 my ($self, $arg) = @_;
731 219 50       849 my $method =
    50          
732             $arg eq FALSE ? \&FALSE : # allow 0/1 as shortcut
733             $arg eq TRUE ? \&TRUE :
734             $arg;
735 219         582 $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         12 $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 4 keys %{ $_[0]->{ symbols } } ? 1 : 0;
  3         19  
753             }
754              
755             sub load {
756 120     120 1 184 my $self = shift;
757 120 50       269 _autoload($self->{ name }) || return;
758 98         329 return $self;
759             }
760              
761             sub maybe_load {
762 54     54 1 87 my $self = shift;
763 54   66     86 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 135 my ($self, $base) = @_;
788 31         68 my $pkg = $self->{ name };
789 31         104 $self->base($base);
790 31         228 $pkg->UBER;
791 31         77 return $self;
792             }
793              
794             sub hooks {
795 31     31 1 70 my $self = shift;
796 31 50       133 my $args = @_ == 1 ? shift : { @_ };
797 31         182 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       207 map { $_ => $_ }
  99         266  
806             @$args
807             } if ref $args eq ARRAY;
808              
809 31 50       142 croak("Invalid hooks specified: $args")
810             unless ref $args eq HASH;
811              
812 31 50       107 _debug("merging $self->{ name } hooks: ", join(', ', keys %$args), "\n") if DEBUG;
813              
814 31         198 @$hooks{ keys %$args } = values %$args;
815              
816 31         135 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   8426 my $class = shift;
828 70     70   522 no strict REFS;
  70         133  
  70         2661  
829 70     70   413 no warnings ONCE;
  70         144  
  70         20705  
830 6391         6762 my $symbols = \%{"${class}::"};
  6391         16722  
831              
832 6391 100 100     7784 unless (
833 6391         42773 defined ${ $class.PKG.LOADED }
834 105081         142951 || scalar(grep { ! /::$/ } keys %$symbols) > 1 # any symbols defined other than import / sub-namespaces
835             ) {
836 649 50       1406 _debug("autoloading $class\n") if DEBUG;
837 649         2740 local $SIG{__DIE__};
838 70     70   29318 eval "use $class";
  70     70   218  
  70     70   1031  
  70     70   37671  
  70     70   233  
  70     70   1062  
  70     68   34541  
  70     44   216  
  70     33   525  
  70     24   32601  
  70         213  
  70         482  
  70         37746  
  70         240  
  70         488  
  70         28854  
  70         216  
  70         1129  
  68         32730  
  68         227  
  68         559  
  44         19294  
  44         11358  
  44         713  
  33         13652  
  32         2108  
  32         458  
  24         10541  
  23         94  
  23         239  
  649         43760  
839 649 100       5296 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         50219 if scalar(grep { ! /::$/ } keys %$symbols) == 1
850 627 0 33     6093 && exists $symbols->{ import };
851              
852 627   100     1936 ${ $class.PKG.LOADED } ||= 1;
  627         4310  
853             }
854              
855 6369         35484 return $class;
856             }
857              
858             sub _debug {
859 0     0     print STDERR @_;
860             }
861              
862              
863             1;
864              
865             __END__