2011-01-10 7 views
3

So nach einer peinlichen Zeit Debugging, habe ich endlich this issue zu einem einfachen Testfall ausgezogen. Ich würde demütig um Hilfe bitten, zu verstehen, warum es scheitert. :) Hier ist die Fehlermeldung erhalte ich:MooseX :: Typen Deklarationsproblem, enger Testfall :)

plxc16479> $h2/tmp/tmp18.pl 
This method [new] requires a single argument. at /nfs/pdx/disks/nehalem.pde.077/perl/5.12.2/lib64/site_perl/MooseX/Types/TypeDecorator.pm line 91 

MooseX::Types::TypeDecorator::new('MooseX::Types::TypeDecorator=HASH(0x655b90)') called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 10 

Program::Plist::Pl::BUILD('Program::Plist::Pl=HASH(0x63d478)', 'HASH(0x63d220)') called at generated method (unknown origin) line 29 

Program::Plist::Pl::new('Program::Plist::Pl') called at /nfs/pdx/disks/nehalem.pde.077/tmp/tmp18.pl line 10 

Wrapper Testskript:

use strict; 
use warnings; 

BEGIN {push(@INC, split(':', $ENV{PERL_TEST_LIBS}))}; 

use Program::Plist::Pl; 

my $obj = Program::Plist::Pl->new(); 

Programm :: Plist :: Pl Datei:

package Program::Plist::Pl; 

use Moose; 
use namespace::autoclean; 

use Program::Types qw(Pattern); # <-- Removing this fixes error 
use Program::Plist::Pl::Pattern; 

sub BUILD { 
    my $pattern_obj = Program::Plist::Pl::Pattern->new(); 
} 

__PACKAGE__->meta->make_immutable; 

1; 

Programm :: Typen Datei:

package Program::Types; 

use MooseX::Types -declare => [qw(Pattern)]; 

class_type Pattern, {class => 'Program::Plist::Pl::Pattern'}; 

1; 

Und das Programm :: Plist :: Pl :: Patte rn-Datei:

package Program::Plist::Pl::Pattern; 

use Moose; 
use namespace::autoclean; 

__PACKAGE__->meta->make_immutable; 

1; 

Hinweise: Während ich von Program::Types in dem obigen Code den Pattern Typen nicht brauchen, ich in anderem Code zu tun, die gezupft wird. Die PERL_TEST_LIBS env var, von der ich INC Pfade abruf, enthält nur Pfade zu den Projektmodulen. Aus diesen Pfaden werden keine anderen Module geladen. Die MooseX::Types Definition für Pattern verursacht Probleme, aber ich bin nicht sicher, warum. Die Dokumentation zeigt die Syntax, die ich verwende, aber es ist möglich, dass ich class_type missbrauche, da nicht viel darüber gesagt wird. Absicht ist, Pattern für Typprüfung über MooseX::Params::Validate verwenden zu können, um zu überprüfen, ob das Argument ein Program::Plist::Pl::Program Objekt ist. direkt von Pattern->new aus den tmp18.pl Wrapper führt zu keinem Fehler aufrufen, auch wenn der Program::TypesPattern Typ importiert

ich gefunden habe, dass die dazwischen liegenden Klasse Program::Plist::Pl aus der Gleichung zu entfernen.

+0

Es scheint, dass Program :: Plist :: Pl :: Pattern-> new mit Pattern-> new verwechselt wird, wobei Pattern mein MooseX-definierter Typ ist.Anstatt eine Instanz von Program :: Plist :: Pl :: Pattern zu erstellen, wird versucht, eine Instanz des Objekts Mustertyp zu erstellen. –

Antwort

5

Wenn Sie sagen,

package Program::Plist::Pl; 
... 
use Program::Types qw(Pattern); 

Sie ein Unterprogramm Pattern in Paket Program::Plist::Pl genannt importieren. Der vollständig qualifizierte Name lautet Program::Plist::Pl::Pattern. Daher

Program::Plist::Pl::Pattern->new(); 

parst als

Program::Plist::Pl::Pattern()->new(); 

statt

'Program::Plist::Pl::Pattern'->new(); 

das ist, was Sie gemeint. Sie können das mit expliziten Anführungszeichen schreiben, wenn Sie wollen (und es wird funktionieren), aber es ist ein lästiger Sonderfall. Eine andere Lösung besteht darin, den Typ in etwas umzubenennen, das nicht in Konflikt mit dem Paketnamen steht (z. B. PatternObj).

namespace::autoclean hilft nicht dabei. Es verhindert, dass importierte Subs als Methoden aufgerufen werden. Aber Sie rufen Program::Plist::Pl::Pattern() direkt auf und rufen dann eine Methode für ihren Rückgabewert auf.

+0

Dies ist übrigens ein guter Grund, Perls Namenskonventionen "Community Standard" zu folgen: TitleCase-Klassennamen, Kleinbuchstaben_Unter_Namen_mit_Unterworten. Wenn Sie TitleCase sowohl für Klassennamen als auch für Unternamen verwenden, sind Konflikte wie diese * extrem * wahrscheinlich aufgrund der Häufigkeit von Objektattributen, die nach der rechten Komponente von Klassennamen benannt sind (zB $ product-> Vendor())/setze ein Product :: Vendor-Objekt). –

+0

cjm - Ja, es scheint jetzt offensichtlich, dass ich den Bug in die Ecke gedrängt habe :) Ich bin nur froh endlich herausgefunden zu haben, was los ist. Das hat mich für DAYS verrückt gemacht. Aber ich habe auch mehr in dieser Zeit gelernt, dann habe ich schon eine ganze Weile gelernt :) John - Sie sind absolut korrekt auf die Benennungsstandards. Ich folge ihnen auf meinem ganzen Code. Allerdings habe ich noch nie zuvor Moose verwendet, und die gesamte Dokumentation, die ich gesehen habe, verwendet die Benennungskonvention für Typdefinitionen von UpperCase, also verwendete ich das scheinbare Benennungsprotokoll. –