MooseX-AbstractFactory
view release on metacpan or search on metacpan
lib/MooseX/AbstractFactory/Role.pm view on Meta::CPAN
package MooseX::AbstractFactory::Role;
use strict;
use warnings;
use Moose::Role;
use Moose::Autobox;
use Module::Runtime qw( use_package_optimistically );
use Try::Tiny;
our $VERSION = '0.004003'; # VERSION
our $AUTHORITY = 'cpan:PENFOLD';
has _options => (is => 'ro', isa => 'ArrayRef[Any]');
has _implementation => (is => 'ro', isa => 'Str');
sub create {
my ($class, $impl, @impl_args) = @_;
if (defined $impl) {
my $factory
= $class->new({
_implementation => $impl,
_options => [ @impl_args ]
});
my $iclass
= $factory->_get_implementation_class(
$factory->_implementation()
);
# pull in our implementation class
$factory->_validate_implementation_class($iclass);
my $iconstructor = $iclass->meta->constructor_name;
my $implementation
= $iclass->$iconstructor(
@{ $factory->_options }
);
# TODO - should we sneak a factory attr onto the metaclass?
return $implementation;
}
else {
confess('No implementation provided');
}
}
sub _get_implementation_class {
my ($self, $impl) = @_;
my $class = blessed $self;
if ($self->meta->has_class_maker) {
return $self->meta->implementation_class_maker->($impl);
}
else {
return $class . "::$impl";
}
}
sub _validate_implementation_class {
my ($self, $iclass) = @_;
try {
# can we load the class?
use_package_optimistically($iclass); # may die if user really stuffed up _get_implementation_class()
if ($self->meta->has_implementation_roles) {
my $roles = $self->meta->implementation_roles();
# create an anon class that's a subclass of it
my $anon = Moose::Meta::Class->create_anon_class();
( run in 2.113 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )