develooper Front page | perl.moose | Postings from March 2009


Thread Next
Ian Sillitoe
March 4, 2009 11:32
Message ID:

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,


=head1 NAME

MooseX::PluginFactory - provides easy access to custom plugins


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 } }


    $param_set1 = My::Algorithm::ParamFactory->plugin_get( 'set1' );

    # equivalent to:
    #   My::Algorithm::Param::Set1->new;

    # foo: 4, bar: 0


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::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.

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About