因此,经过一段令人尴尬的调试时间后,我终于将this issue剥离为一个简单的测试用例。我会谦卑地请求帮助理解为什么它会失败。 :)这是我收到的错误消息:
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
包装测试脚本:
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;
程序::类型文件:
package Program::Types;
use MooseX::Types -declare => [qw(Pattern)];
class_type Pattern, {class => 'Program::Plist::Pl::Pattern'};
1;
Program :: Plist :: Pl :: Pattern文件:
package Program::Plist::Pl::Pattern;
use Moose;
use namespace::autoclean;
__PACKAGE__->meta->make_immutable;
1;
注意:虽然我在上面的代码中不需要Pattern
中的Program::Types
类型,但我会在其他代码中删除。我从PERL_TEST_LIBS
路径中提取的INC
env var仅包含项目模块的路径。没有从这些路径加载其他模块。
Pattern
的{{3}}定义似乎导致了问题,但我不确定原因。文档显示了我正在使用的语法,但是我可能会误用class_type
,因为没有太多关于它的说法。意图是能够通过MooseX::Types使用Pattern
进行类型检查,以验证参数是Program::Plist::Pl::Program
对象。
我发现,通过直接调用Program::Plist::Pl
包装中的Pattern->new
,从等式中移除干预类tmp18.pl
会导致错误,即使Program::Types
{{导入{1}}类型。
答案 0 :(得分:5)
当你说
时package Program::Plist::Pl;
...
use Program::Types qw(Pattern);
您要将名为Pattern
的子例程导入包Program::Plist::Pl
。其完全限定名称为Program::Plist::Pl::Pattern
。因此,
Program::Plist::Pl::Pattern->new();
解析为
Program::Plist::Pl::Pattern()->new();
而不是
'Program::Plist::Pl::Pattern'->new();
这就是你的意思。如果你愿意,你可以使用显式引号来编写它(并且它可以工作),但这是一个恼人的特殊情况。另一种解决方案是将类型重命名为不会与包名称冲突的内容(例如PatternObj
)。
namespace::autoclean对此没有帮助。它阻止人们调用导入的subs作为方法。但是你直接调用Program::Plist::Pl::Pattern()
,然后在返回值上调用方法。