2009-07-20 7 views
5

Tengo dificultades con el método BUILD en MooseX::Declare. Si digo:¿Cuál es la forma correcta de crear un método BUILD en 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; 

me sale el siguiente menos atento mensaje de error:

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 

Pero si digo:

#!/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; 

todo funciona muy bien (pero es feo y fuera de lugar con el resto del código).

Respuesta

-2

Perl comprende sub y, por lo tanto, se realiza una entrada en la tabla de símbolos del paquete actual. & Foo :: BUILD, después de Devel::Declare y otra magia ha creado un alcance de paquete del cierre de clase.

Moose busca específicamente el sub BUILD para permitirle manipular la lógica del constructor. Mi suposición (aunque no lo he rastreado hasta el final) es que los módulos de MooseX no interfieren con lo que Moose está tratando de hacer. De modo que un BUILD nativo pasa para siempre a la magia de Moose para determinar la lógica del constructor.

Por otro lado, la palabra clave method es más Devel::Declare mágica para crear métodos en la estructura de metaclase.

5

Está fallando porque BUILD requiere una firma de método de una arg. De forma predeterminada, MooseX::Declare crea una firma que no es compatible con la forma en que se llama al BUILD. (Los detalles son oscuros para mí.) Lo sé porque me encontré con un error similar una vez. Ciertamente estoy de acuerdo en que el mensaje de error podría ser más esclarecedor; eso es cierto con muchas cosas de Moose.

De todos modos, lo tengo para trabajar de esta manera:

use MooseX::Declare; 

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

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

Foo->new; 

Espero que ayude.

Puede juguetear con la firma y probar tipos más específicos; Creo que Moose envía un hashref del objeto aún no otorgado como parámetro.

+0

Wow, eso es feo, 'existe $ self' y tiene el objeto bendito, sino que también tiene este hashref inútil lleno de los argumentos pasados ​​a 'nuevo'. Esta es una gran verruga en lo que de otra manera sería un hermoso sistema. –

+0

Esta "verruga" tal vez algo que se eliminará. Cuando mires los documentos antiguos (http://search.cpan.org/~drolsky/Moose-0.65/lib/Moose/Cookbook/Basics/Recipe4.pod) verás que se necesita un param hashref arg adicional. Sin embargo, en los documentos nuevos (http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Basics/Recipe4.pod) ahora puede usar $ self direct para acceder a los "params". ¡Entonces tal vez sea parte de un proceso evolutivo en el que se dejará este paramé adicional! La lista de correo de Moose/IRC es el mejor lugar para averiguar si todavía se necesita "params" arg y cuáles son los planes darwinianos ;-) – draegtun

+0

¿Un argumento para un método es una "verruga importante"? No me gustaría escuchar lo que piensas del sistema de objetos C++ o Java ... – jrockway

6

BUILD toma un arg, si usted no lo necesita, simplemente decir:

method BUILD($) { ... } 
Cuestiones relacionadas