2009-07-20 9 views
5

Ho difficoltà con il metodo BUILD in MooseX::Declare. Se dico:Qual è il modo corretto di creare un metodo BUILD in MooseX :: Declare?

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

ottengo il seguente meno di messaggio di errore utile:

Reference found where even-sized list expected at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 335. 
Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types::Structured::Tuple[Object],MooseX::Types::Structured::Dict[]]' failed with value [ [ Foo=HASH(0x804b20) ], { HASH(0x8049e0) => undef } ], Internal Validation Error is: Validation failed for 'MooseX::Types::Structured::Dict[]' failed with value { HASH(0x8049e0) => undef } at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 365 
     MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0xb8aab0)', 'ARRAY(0xb8ab30)') called at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 139 
     Foo::BUILD('Foo=HASH(0x804b20)', 'HASH(0x8049e0)') called at generated method (unknown origin) line 25 
     Foo::new('Foo') called at test.pl line 13 

Ma se io dico:

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    sub BUILD { 
     my $self = shift; 
     print "I was called\n"; 
    } 
} 

Foo->new; 

tutto funziona bene (ma è brutto e fuori di posto con il resto del codice).

risposta

-2

Perl capisce sub e quindi viene inserita una voce nella tabella dei simboli del pacchetto corrente. & Foo :: BUILD, dopo Devel::Declare e altra magia ha creato un ambito del pacchetto dalla chiusura della classe.

Moose in particolare cerca il sub BUILD per consentire di manipolare la logica del costruttore. La mia ipotesi (sebbene non l'abbia tracciata fino in fondo) è che i moduli MooseX si tengano alla larga da ciò che Moose sta cercando di fare. In modo che un nativo BUILD venga passato per sempre alla magia Moose per determinare la logica del costruttore.

D'altra parte la parola chiave method è più Devel::Declare magica per creare metodi nella struttura di metadati.

5

Non funziona perché BUILD richiede una firma del metodo di un argo. Per impostazione predefinita, MooseX::Declare crea una firma che non è compatibile con il modo in cui viene chiamato BUILD. (I dettagli sono oscuri per me.) Lo so perché mi sono imbattuto in un errore simile una volta. Sono certamente d'accordo sul fatto che il messaggio di errore potrebbe essere più illuminante; questo è vero con molte cose Moose.

In ogni caso, ho preso a lavorare in questo modo:

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD(Item $href) { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

Speranza che aiuta.

È possibile armeggiare con la firma e provare tipi più specifici; Penso che Moose manda un hashref dell'oggetto come ancora non benedetto come parametro.

+0

Wow, che è brutto, 'esiste $ self' e contiene l'oggetto benedetto, ma hai anche questo rifhash inutile pieno degli argomenti passati in 'nuovo'. Questa è una grande verruca su quello che altrimenti è un bel sistema. –

+0

Questa "verruca" potrebbe essere qualcosa che verrà rimosso. Quando guardi i vecchi documenti (http://search.cpan.org/~drolsky/Moose-0.65/lib/Moose/Cookbook/Basics/Recipe4.pod) vedrai che è necessario un ulteriore parametro hashref arg. Tuttavia nei nuovi documenti (http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Basics/Recipe4.pod) ora puoi usare $ self direct per accedere ai "parametri". Quindi forse parte di un processo evolutivo in cui questo extra param verrà abbandonato! La mailing list delle alci/IRC è il posto migliore per scoprire se l'argomento "params" è ancora necessario e quali sono i piani darwiniani ;-) – draegtun

+0

Un argomento per un metodo è una "grande verruca"? Non oso sentire cosa pensi del sistema di oggetti C++ o Java ... – jrockway

6

BUILD prende un arg, se non ne hai bisogno, basta dire:

method BUILD($) { ... } 
Problemi correlati