MooseX::Types declaration issue, tight test case :)
So after an embarrassing amount of time debugging, I've finally stripped this issue down to a simple test case. I would humbly request some help understanding why it's failing. :) Here is the error message I'm getting:
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 test script:
use strict;
use warnings;
BEGIN {push(@INC, split(':', $ENV{PERL_TEST_LIBS}))};
use Program::Plist::Pl;
my $obj = Program::Plist::Pl->new();
Program::Plist::Pl file:
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;
Program::Types file:
package Program::Types;
use MooseX::Types -declare => [qw(Pattern)];
class_type Pattern, {class => 'Program::Plist::Pl::Pattern'};
1;
And the Program::Plist::Pl::Pattern file:
package Program::Plist::Pl::Pattern;
use Moose;
use namespace::autoclean;
__PACKAGE__->meta->make_immutable;
1;
Notes: While I don't need the Pattern
type from Program::Types
in the above code, I do in other code that is stripped out. The PERL_TEST_LIBS
env var from which I'm pulling INC
paths only contains paths to the project modules. There are no other modules loaded from these paths.
It appears the MooseX::Types definition for Pattern
is causing problems, but I'm not sure why. Documentation shows the syntax I am using, but it's possible I'm misusing class_type
as there isn't much said about it. Intent is to be able to use Pattern
for type checking via MooseX::Params::Validate to verify the argument is a Program::Plist::Pl::Program
object.
I've found that removing the intervening class Program::Plist::Pl
from the equation by directly calling Pattern->new
from the tmp18.pl
wrapper results in no error, even when the Program::Types
Pattern
type is imported.
When you say
package Program::Plist::Pl;
...
use Program::Types qw(Pattern);
you are importing a subroutine named Pattern
into package Program::Plist::Pl
. Its fully-qualified name is Program::Plist::Pl::Pattern
. Therefore,
Program::Plist::Pl::Pattern->new();
parses as
Program::Plist::Pl::Pattern()->new();
instead of
'Program::Plist::Pl::Pattern'->new();
which is what you meant. You can write that with explicit quotes if you want (and it will work), but it's an annoying special case. Another solution is to rename the type to something that won't conflict with the package name (say PatternObj
).
namespace::autoclean doesn't help with this. It prevents people from calling imported subs as methods. But you're calling Program::Plist::Pl::Pattern()
directly, and then calling a method on its return value.
精彩评论