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

发布于 2024-10-11 11:37:09 字数 2524 浏览 6 评论 0原文

因此,经过一段令人尴尬的时间调试后,我终于解决了 这个问题 简化为一个简单的测试用例。我会谦虚地请求一些帮助来理解它失败的原因。 :) 这是我收到的错误消息:

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在上面的代码中不需要来自 Program::TypesPattern 类型,我在其他被删除的代码中需要。我从中提取 INC 路径的 PERL_TEST_LIBS 环境变量仅包含项目模块的路径。没有从这些路径加载其他模块。

看来 PatternMooseX::Types 定义引起了问题,但我不知道为什么。文档显示了我正在使用的语法,但我可能误用了 class_type 因为对此没有太多说明。目的是能够通过 MooseX:: 使用 Pattern 进行类型检查Params::Validate 用于验证参数是否为 Program::Plist::Pl::Program 对象。

我发现通过直接从 tmp18.pl< 调用 Pattern->new 从等式中删除介入类 Program::Plist::Pl即使导入 Program::Types Pattern 类型,/code> 包装器也不会产生错误。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁梦 2024-10-18 11:37:09

当您说

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 对此没有帮助。它可以防止人们将导入的子程序调用为方法。但是您直接调用 Program::Plist::Pl::Pattern(),然后在其返回值上调用方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文