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 )