Hello, I found myself writing out the same code for factory objects that provide the loading/selecting of 'plugin' modules. Simple stuff - just annoying to keep retyping the same load/lookup code.
I couldn't see anything obvious on CPAN (maybe MooseX::Object::Plugable could be used but this seems more to be about applying plugins to a given object rather than providing a factory?). I've typed out a synopsis and I figured I would post it here since if it isn't already in MooseX I could well be doing something stupid (I figure it's better to know these things). Failing that - I figured it might save someone else some typing. Comments welcome - cheers, Ian =head1 NAME MooseX::PluginFactory - provides easy access to custom plugins =head1 SYNOPSIS Define factory object package My::Algorithm::ParamFactory; use My::Moose; with 'MooseX::PluginFactory'; sub plugin_base { 'My::Algorithm::Param' } Define plugin modules however you want to: # plugin base class package My::Algorithm::Param; use My::Moose; has 'foo', is => 'ro', isa => 'Int', required => 1; has 'bar', is => 'ro', isa => 'Int', required => 1, default => 0; sub to_string { my $self = shift; sprintf "foo: %s, bar: %s", $self->foo, $self->bar } # plugins package My::Algorithm::Param::Set1; use My::Moose; extends 'My::Algorithm::Param'; sub BUILDARGS { { foo => 4 } } package My::Algorithm::Param::Set2; use My::Moose; extends 'My::Algorithm::Param'; sub BUILDARGS { { foo => 10, bar => 4 } } Elsewhere... $param_set1 = My::Algorithm::ParamFactory->plugin_get( 'set1' ); # equivalent to: # My::Algorithm::Param::Set1->new; $param_set1->to_string; # foo: 4, bar: 0 =head1 DESCRIPTION I found myself writing the same code to help create factories that manage the creation of a bunch of related "plugin" modules, e.g. My::View::Text My::View::HTML My::View::XML My::ViewFactory->get( 'HTML' ); # My::View::HTML This kind of thing is useful when you want to coerce objects from strings: package My::App; use Moose::Util::TypeConstraints; subtype 'My.View' => as 'Object' => where { $_->isa( My::View ) }; coerce 'My.View' => from 'Str' => via { My::ViewFactory->new( $_ ) }; has 'view', isa => 'My.View', coerce => 1; Which allows: $app = My::App->new( view => 'HTML' ); $app->view; # My::View::HTML This is kind of like getting the benefits of string validating (e.g. enum from Moose::Util::TypeConstraints), however you also get the benefits of storing instantiated objects rather than just strings.