MooseX ::类型声明问题,严密的测试用例:)

时间:2011-01-10 23:28:32

标签: perl moose moosex-types

因此,经过一段令人尴尬的调试时间后,我终于将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}}类型。

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(),然后在返回值上调用方法。