2009-07-07 6 views
21

Ho scritto un set di classi e interfacce implementate in Moose utilizzando anche i ruoli. Quello che ho difficoltà a capire sono le differenze esatte nell'uso e nell'implementazione dei tratti Moose rispetto ai ruoli.In che modo i ruoli e i tratti differiscono in Moose?

I Moose documentation stati:

E 'importante capire che i ruoli e le caratteristiche sono la stessa cosa. Un ruolo può essere usato come tratto e un tratto è un ruolo. L'unica cosa che distingue i due è che un tratto è confezionato in un modo che consente a Moose di risolvere un nome breve con un nome di classe. In altre parole, con un tratto, il chiamante può riferirsi ad esso con un nome breve come "Big", e Moose lo risolverà in una classe come MooseX :: Embiggen :: Meta :: Attribute :: Role :: Big.

È a mia conoscenza che tratti e ruoli sono "uguali". Tuttavia, quando si implementa un test di base dell'idea utilizzando la sintassi use Moose -traits 'Foo' non sembra fare ciò che mi aspetterei. Sicuramente mi mancherà qualcosa qui.

Questo primo esempio viene a mancare con "Impossibile trovare il metodo oggetto 'foo'"

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 
__PACKAGE__->foo(); #Can't locate object method 'foo' 

Rispetto a questo (che funziona):

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose; 
with 'MyApp::Meta::Class::Trait::HasTable'; 
__PACKAGE__->foo(); #foo 

risposta

12

Questa è l'unica differenza in come Moose utilizza i termini "Tratto" e "Ruolo". La documentazione e le API di Moose usano spesso il termine "tratti" come "Ruoli applicati a Metaclasses" . Nella tua risposta rivista, il tuo primo esempio applica il ruolo al metacarodo di MyApp::User tramite -traits, il secondo esempio lo applica alla classe .

Se si cambia il primo esempio a:

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 
__PACKAGE__->meta->foo(); 

Vedrai "foo at [script]. line 3." Il che è esattamente quello che dovrebbe essere facendo.

AGGIORNAMENTO: Apparentemente non sono esattamente corretto qui. I tratti sono ruoli applicati alle istanze. L'hook -traits applica HasTable all'istanza metaclass per MyApp :: User. Ho aggiornato i documenti Moose pertinenti.

+0

Grazie, questo spiega il comportamento che stavo vedendo. – Danny

+1

Ho aggiornato il testo in Extending/Recipe1.pod per cercare di riflettere un po 'questa differenza. Nota anche per confondere le cose più Le cose simili a ruoli sono chiamate Tratti in altri linguaggi come Scala. Questi tratti sono definiti in alcuni documenti che hanno informato l'origine dell'implementazione del ruolo di Moose ma mancano delle funzionalità di trasporto dello stato (ovvero sono solo metodi e non hanno attributi). – perigrin

0

Lei non definiscono una pacchetto 'x :: Foo' con qualsiasi ruolo. Strappato direttamente dal documentation, vediamo che register_implementation restituisce il nome di un pacchetto effettivamente definito:

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 

has table => (
    is => 'rw', 
    isa => 'Str', 
); 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 

__PACKAGE__->meta->table('User'); 

La "scorciatoia" si ottiene Moose alla ricerca di "Moose::Meta::Class::Trait::$trait_name" (quando viene chiamato in un "contesto di classe"), e non solo restituire un nome più breve.

+0

Si prega di vedere la mia revisione alla mia domanda, ho cercato di aggiungere ulteriori dettagli. – Danny

Problemi correlati