2009-07-20 6 views
5

J'ai des difficultés avec la méthode BUILD en MooseX::Declare. Si je dis:Quelle est la bonne façon de créer une méthode BUILD dans 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; 

Je reçois le texte suivant moins utile message d'erreur:

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 

Mais si je dis:

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

tout fonctionne très bien (mais est laid et hors de lieu avec le reste du code).

Répondre

-2

Perl comprend sub et donc une entrée dans la table de symboles du paquet courant est faite. & Foo :: BUILD, après Devel::Declare et une autre magie a créé une portée de paquet à partir de la fermeture de la classe.

Moose recherche spécifiquement le sous-élément BUILD pour vous permettre de manipuler la logique du constructeur. Ma conjecture (bien que je ne l'ai pas retracée tout au long) est que les modules MooseX restent à l'écart de ce que Moose essaie de faire. Alors qu'un BUILD natif est définitivement passé à la magie Moose pour déterminer la logique du constructeur.

D'autre part, le mot-clé method est plus Devel::Declare magique pour créer des méthodes dans la structure de classe meta.

5

Il échoue car BUILD nécessite une signature de méthode à un seul argument. Par défaut, MooseX::Declare crée une signature qui n'est pas compatible avec la façon dont BUILD est appelée. (Les détails sont obscurs pour moi.) Je sais parce que j'ai rencontré une erreur similaire une fois. Je suis certainement d'accord que le message d'erreur pourrait être plus éclairant; c'est vrai avec beaucoup de choses Moose.

Quoi qu'il en soit, je l'ai eu à travailler comme ça:

use MooseX::Declare; 

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

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

Foo->new; 

espoir qui aide.

Vous pouvez bidouiller la signature et essayer des types plus spécifiques; Je pense que Moose envoie un hashref de l'objet non encore béni comme paramètre.

+0

Wow, ce qui est laid, 'self' de $ existe et contient l'objet béni, mais vous avez aussi ce hashref inutile plein des arguments passés dans 'new'. C'est une verrue majeure sur ce qui est autrement un beau système. –

+0

Cette "verrue" peut-être quelque chose qui va être enlevé. Quand vous regardez vieux docs (http://search.cpan.org/~drolsky/Moose-0.65/lib/Moose/Cookbook/Basics/Recipe4.pod) vous verrez que l'argument supplémentaire de paramètre hashref est nécessaire. Cependant, dans les nouveaux documents (http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Basics/Recipe4.pod), vous pouvez maintenant utiliser $ self direct pour accéder aux "params". Alors peut-être partie d'un processus évolutif où ce paramètre supplémentaire sera déposé! Moose mailing list/IRC est le meilleur endroit pour savoir si "params" arg est encore nécessaire et quels sont les plans darwiniens ;-) – draegtun

+0

Un argument à une méthode est une "verrue majeure"? Je n'aimerais pas entendre ce que vous pensez du système objet C++ ou Java ... – jrockway

6

BUILD prend un arg, si vous n'avez pas besoin, juste dire:

method BUILD($) { ... } 
Questions connexes