2009-07-20 4 views
5

Ich habe Schwierigkeiten mit der BUILD Methode in MooseX::Declare. Wenn ich sage:Was ist der richtige Weg, um eine BUILD-Methode in MooseX :: Declare zu erstellen?

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

ich die folgenden weniger als hilfreich Fehlermeldung:

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 

Aber wenn ich sage:

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

alles funktioniert gut (aber ist hässlich und aus von Ort mit dem Rest des Codes).

Antwort

-2

Perl versteht sub und so wird ein Eintrag in die Symboltabelle des aktuellen Pakets gemacht. & Foo :: BUILD, nach Devel::Declare und andere Magie hat einen Paketbereich von der Klassenschließung erstellt.

Moose sucht speziell nach dem BUILD Sub, um Ihnen zu ermöglichen, Konstruktorlogik zu manipulieren. Meine Vermutung (obwohl ich es nicht bis zum Ende durchgespielt habe) ist, dass die MooseX-Module dem, was Moose versucht, aus dem Weg gehen. Damit wird ein nativer BUILD für immer an die Elchmagie übergeben, um Konstruktorlogik zu bestimmen.

Auf der anderen Seite ist das Schlüsselwort method mehr Devel::Declare Magie, um Methoden in der Meta-Klassenstruktur zu erstellen.

5

Es schlägt fehl, weil BUILD eine Signatur-Signatur erfordert. Standardmäßig erstellt MooseX::Declare eine Signatur, die nicht mit der Art kompatibel ist, wie BUILD aufgerufen wird. (Die Einzelheiten sind mir unklar.) Ich weiß, weil ich einmal auf einen ähnlichen Fehler gestoßen bin. Ich stimme sicherlich zu, dass die Fehlermeldung aufschlussreicher sein könnte; das stimmt mit einer Menge Elch Zeug.

Wie dem auch sei, ich habe es wie folgt zu arbeiten:

use MooseX::Declare; 

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

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

Foo->new; 

Hoffnung, das hilft.

Sie können mit der Signatur herumfummeln und spezifischere Typen ausprobieren; Ich denke, Moose sendet einen Hashref des noch nicht geblendeten Objekts als Parameter.

+0

Wow, das ist hässlich, '$ self' existiert und hält das gesegnete Objekt, aber auch diese nutzlose hashref haben voller Argumente in "neu". Dies ist eine große Warze auf was ist sonst ein schönes System. –

+0

Diese "Warze" ist vielleicht etwas, das entfernt wird. Wenn Sie sich alte Dokumente anschauen (http://search.cpan.org/~drolsky/Moose-0.65/lib/Moose/Cookbook/Basics/Recipe4.pod), werden Sie sehen, dass extra param hashref arg benötigt wird. In neuen Dokumenten (http://search.cpan.org/dist/Moose/lib/Moose/Cookbook/Basics/Recipe4.pod) können Sie jetzt $ self direct verwenden, um auf die "params" zuzugreifen. Also vielleicht Teil eines evolutionären Prozesses, bei dem dieser zusätzliche Parameter fallengelassen wird! Moose Mailingliste/IRC ist der beste Ort, um herauszufinden, ob "Params" noch benötigt wird und was die Darwinschen Pläne sind ;-) – draegtun

+0

Ein Argument für eine Methode ist eine "große Warze"? Ich würde es hassen zu hören, was Sie über das C++ - oder Java-Objektsystem denken ... – jrockway

6

BUILD nimmt einen arg, wenn Sie es nicht brauchen, sagen Sie einfach:

method BUILD($) { ... }