What is the best option for building a plugin system for a Moose application?

南楼画角 提交于 2019-11-29 00:24:38

There are a few ways to provide extensibility; allow the user to apply roles to your class, or allow them to pass in small objects that do the interesting things (delegates). Delegates perform better than roles, but will require that you plan for all the extensibility up front. Roles allow more ad-hoc behaviors.

Here are two CPAN distributions that take each approach:

Delegates: AnyEvent::Subprocess

Roles: Devel::REPL

Plugin roles are implemented with MooseX::Object::Pluggable.

Delegates are implemented however you like; the pattern is passing an instance of a class A that does some role R to class C, and then class C delegates to A. Here's an example:

package Compare;
use Moose::Role;
requires 'compare';


package SpaceshipCompare;
use Moose;
with 'Compare';  

sub compare { my ($a, $b) = @_; return $a <=> $b }

package Sort;
use Moose;

has 'comparer' => (
    is       => 'ro',
    does     => 'Compare',
    handles  => 'Compare',
    required => 1,
);

sub my_sort {
    my ($self, @list) = @_;
    return sort { $self->compare($a, $b) } @list;
}

Then you use this like:

my $sorter = Sort->new( comparer => SpaceshipCompare->new );
my @sorted = $sorter->my_sort("1one", "0", "43");

If you want the way Sort works to change, you just create a new class that does the Compare role, and then pass an instance to Sort's constructor. Instant flexibility!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!