Badger
view release on metacpan or search on metacpan
lib/Badger/Modules.pm view on Meta::CPAN
use Badger::Debug ':dump';
use Badger::Class
version => 0.01,
debug => 0,
base => 'Badger::Prototype Badger::Exporter',
import => 'class',
utils => 'plural blessed textlike dotid camel_case',
accessors => 'item items',
words => 'ITEM ITEMS ISA TOLERANT BADGER_LOADED',
constants => 'PKG ARRAY HASH REFS ONCE DEFAULT',
constant => {
OBJECT => 'object',
FOUND => 'found',
FOUND_REF => 'found_ref',
PATH_SUFFIX => '_PATH',
NAMES_SUFFIX => '_NAMES',
DEFAULT_SUFFIX => '_DEFAULT',
},
methods => {
init => \&init_modules,
throws => \&item,
},
messages => {
no_item => 'No item(s) specified for factory to manage',
no_default => 'No default defined for %s factory',
bad_ref => 'Invalid reference for %s factory item %s: %s',
bad_method => q{Can't locate object method "%s" via package "%s" at %s line %s},
failed => q{Error loading %s module %s as %s: %s},
};
our $ITEM = 'module';
sub init_modules {
my ($self, $config) = @_;
my $class = $self->class;
my ($item, $items);
$self->debug("initialising modules: ", $self->dump_data($config)) if DEBUG;
$config->{ tolerant } = $class->any_var(TOLERANT)
unless defined $config->{ tolerant };
# 'item' and 'items' can be specified as config params or we look for
# $ITEM and $ITEMS variables in the current package or those of any
# base classes. NOTE: $ITEM and $ITEMS must be in the same package
unless ($item = $config->{ item }) {
foreach my $pkg ($class->heritage) {
no strict REFS;
no warnings ONCE;
if (defined ($item = ${ $pkg.PKG.ITEM })) {
$items = ${ $pkg.PKG.ITEMS };
last;
}
}
}
return $self->error_msg('no_item')
unless $item;
# use 'items' in config, or grokked from $ITEMS, or guess plural
$items = $config->{ items } || $items || plural($item);
my $ipath = $item.PATH_SUFFIX;
my $inames = $item.NAMES_SUFFIX;
my $idefault = $item.DEFAULT_SUFFIX;
# Merge all XXXX_PATH package vars with any 'xxxx_path' or 'path' config
# items. Ditto for XXXX_NAME / 'xxxx_name' / 'aka' and XXXXS/ 'xxxxs'
my @path = @$config{ path => lc $ipath };
my @names = @$config{ names => lc $inames };
$self->{ path } = $class->list_vars(uc $ipath, @path);
$self->{ names } = $class->hash_vars(uc $inames, @names);
$self->{ $items } = $class->hash_vars(uc $items, $config->{ $items }); # TODO: this could clash
$self->{ tolerant } = $config->{ tolerant };
$self->{ items } = $items;
$self->{ item } = $item;
$self->{ loaded } = { }; # TODO: make this the same thing?
$self->debug(
" Item: $self->{ item }\n",
"Items: $self->{ items }\n",
" Path: ", $ipath, ": ", $self->dump_data($self->{ path }), "\n",
"Names: ", $inames, ": ", $self->dump_data($self->{ names })
) if DEBUG;
return $self;
}
sub path {
my $self = shift->prototype;
return @_
? ($self->{ path } = ref $_[0] eq ARRAY ? shift : [ @_ ])
: $self->{ path };
}
sub names {
my $self = shift->prototype;
my $names = $self->{ names };
if (@_) {
my $args = ref $_[0] eq HASH ? shift : { @_ };
@$names{ keys %$args } = values %$args;
}
return $names;
}
sub module_names {
my $self = shift;
my @bits =
map { camel_case($_) }
map { split /[\.]+/ } @_;
my %seen;
return (
grep { ! $seen{ $_ }++ }
join( PKG, map { ucfirst $_ } @bits ),
join( PKG, @bits )
( run in 2.512 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )