2011-01-27 10 views
5

Desidero scrivere un'app che può essere estesa tramite plugin, utilizzando Perl e Moose. So che ci sono alcuni moduli Moose per scrivere plugin e so che ci sono altri modi.Qual è l'opzione migliore per creare un sistema di plugin per un'applicazione Moose?

Quali sono le mie opzioni? e cosa dovrei sapere su di loro? qualsiasi cosa dovrei pensare prima di implementare un sistema di plugin?

+1

Hai esaminato [Module :: Pluggable] (http://search.cpan.org/~simonw/Module-Pluggable-3.9/lib/Module/Pluggable.pm)? –

+0

@Len Ho dato un'occhiata a diversi moduli in una volta, ma preferirei imparare dall'esperienza comunitaria. Penso di averne trovato almeno 3 diversi e di aver letto anche altri modi. Non so perché esistano così tanti modi e quale sia la differenza. TIMTOWTDI, ma di solito c'è una ragione per cui esiste più di un modo. – xenoterracide

risposta

5

Esistono alcuni modi per fornire l'estensibilità; consentire all'utente di applicare i ruoli alla classe, o consentire loro di passare in piccoli oggetti che fanno le cose interessanti (delegati). I delegati si comportano meglio dei ruoli, ma richiedono di pianificare tutta l'estensibilità in anticipo. I ruoli consentono comportamenti più ad-hoc.

Ecco due distribuzioni CPAN che prendono ogni approccio:

delegati: AnyEvent::Subprocess

ruoli: Devel::REPL

ruoli plugin sono implementate tramite MooseX::Object::Pluggable.

I delegati sono implementati come preferisci; il modello sta passando un'istanza di una classe A che fa qualche ruolo R alla classe C, e quindi di classe C delegati al A. Ecco un esempio:

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

quindi si utilizza questo tipo:

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

Se si desidera che il metodo Sort funzioni, è sufficiente creare una nuova classe con il ruolo Compare e quindi passare un'istanza al costruttore di Sort. Flessibilità istantanea!

+0

ogni caso si conosce il diff tra MooseX :: Object :: Pluggable e Module :: Pluggable? – xenoterracide

+0

@xenoterracide MooseX :: Object :: Pluggable applica i ruoli alla classe corrente in base a uno spazio dei nomi. Module :: Pluggable fornisce un elenco di namespace/istanze. Sono quasi completamente diversi oltre la parte "look up namespaces". – perigrin

+0

+1 per l'eccezionale esempio – qodeninja

Problemi correlati