- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近遇到了一个问题,非常感谢任何见解。圣诞节前,我在 PerlMonks 上发布了一个类似的问题,并提供了一些关于从 MooseX::Declare ([http://www.perlmonks.org/?node_id=877703][1]) 切换的反馈。我现在已经将代码切换到带有 MooseX::Types 和 MooseX::Params::Validate 的 vanilla Moose。然而,同样的错误发生在同一个地方。不足为奇,因为它似乎与 MooseX::Types 相关。
我收到以下错误(为了便于阅读,尝试将其分隔开和堆栈底部被截断):
plxc16479> tmp10.pl
Argument cannot be 'name' at /nfs/pdx/disks/nehalem.pde.077/perl/lib64/site_perl/MooseX/Types/TypeDecorator.pm line 88
MooseX::Types::TypeDecorator::new('MooseX::Types::TypeDecorator=HASH(0x1620c58)', 'name', 'g1145114N5582201_16161616a2x_FU02xxT_2bxc2e3_6x0xxxp0fx0xxx0x...', 'mask_data', '', 'tags', 0) called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 61
Program::Plist::Pl::_create_pattern_obj(undef, 'name', 'g1145114N5582201_16161616a2x_FU02xxT_2bxc2e3_6x0xxxp0fx0xxx0x...', 'mask_data', '', 'tag_data', '') called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 77
Program::Plist::Pl::BUILD('Program::Plist::Pl=HASH(0x162d6c0)', 'HASH(0x162d648)') called at generated method (unknown origin) line 101
Program::Plist::Pl::new('Program::Plist::Pl', 'name', 'bist_hfmmin_16161616_list', 'parents', 'HASH(0xccf040)', 'fh', 'GLOB(0xccc928)', 'external_pl_code', 'CODE(0x14910b0)', ...) called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Roles-PlHandler/lib/Program/Roles/PlHandler.pm line 52
Program::Roles::PlHandler::_create_global_pl_obj(undef, 'name', 'bist_hfmmin_16161616_list', 'parents', 'HASH(0xccf040)', 'fh', 'GLOB(0xccc928)') called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Plist-Pl/lib/Program/Plist/Pl.pm line 77
Program::Plist::Pl::BUILD('Program::Plist::Pl=HASH(0xccd300)', 'HASH(0xccc628)') called at generated method (unknown origin) line 101
Program::Plist::Pl::new('Program::Plist::Pl', 'name', 'bist_list', 'parents', 'HASH(0xccce80)', 'fh', 'GLOB(0xccc928)', 'external_pl_code', 'CODE(0x14910b0)', ...) called at /nfs/pdx/disks/nehalem.pde.077/projects/lib/Program-Roles-PlHandler/lib/Program/Roles/PlHandler.pm line 52
问题 i 似乎是对 TypeDecorator::new 的最高调用。 TypeDecorator 构造函数似乎需要两个参数,class/self 参数和对 TypeDecorator 或 TypeConstraint 对象的引用。相反,它以某种方式接收来 self 的创建模式对象调用的参数。我已经验证进入 _create_pattern_obj 函数的参数是正确的,并且进入 Pattern->new 调用的参数也是正确的(由堆栈跟踪参数证实)。 _create_pattern_obj 函数如下所示:
sub _create_pattern_obj {
my ($self, $name, $mask_data, $tag_data) = validated_list(\@_,
name => {isa => Str},
mask_data => {isa => Str, optional => 1},
tag_data => {isa => Str, optional => 1});
$mask_data = '' if !defined $mask_data;
my $tags = defined $tag_data ? map {$_ => 1} split(',', $tag_data) : {};
my $pattern_obj = Program::Plist::Pl::Pattern->new(name => $name,
mask_data => $mask_data,
tags => $tags);
$self->_add_pattern($pattern_obj);
}
函数死于 Program::Plist::Pl::Pattern->new 调用,即第 61 行在上述调用堆栈中引用的文件 Pl.pm 文件中,其中 TypeDecorator::new 调用声称来自。
模式类是:
package Program::Plist::Pl::Pattern;
use 5.012002;
our $VERSION = sprintf "2.%03d", q($Revision: 473 $) =~ /: (\d+)/;
use Moose;
use namespace::autoclean;
use MooseX::Types::Moose qw(Str Num Int HashRef);
use MooseX::Params::Validate;
has 'name' => (isa => Str,
is => 'ro',
required => 1);
has 'tuple' => (isa => Int,
is => 'ro');
has 'tid' => (isa => Int,
is => 'ro');
has 'weight' => (isa => Num,
is => 'ro');
has 'tags' => (isa => HashRef[Str],
is => 'ro',
default => sub {{}});
has 'mask_data' => (isa => Str,
is => 'rw',
default => '',
writer => '_set_mask_data');
sub has_tag {
my ($self, $tag) = (shift,
pos_validated_list(\@_, {isa => Str}));
exists $self->{tags}->{$tag} ? return 1 : return 0;
}
sub _add_tag {
my ($self, $tag) = (shift,
pos_validated_list(\@_, {isa => Str}));
$self->{tags}->{$tag} = 1;
}
sub BUILDARGS {
print STDERR 'CALLED '.__PACKAGE__."BUILDARGS\n";
print STDERR 'ARGUMENTS:'.join(',', @_)."\n";
}
sub BUILD {
my ($self) = @_;
print STDERR 'CALLED '.__PACKAGE__."::BUILD\n";
}
__PACKAGE__->meta->make_immutable;
1;
不知何故,从调用堆栈中的参数来看,我对 Pattern->new 调用的参数最终被传递给了 TypeDecorator::new 调用并且它正在阻塞它们。我已经验证了对这个子例程的良好调用(来自和更早的堆栈跟踪)看起来像这样(注意两个参数):
数据库<1> T
$ = MooseX::Types::TypeDecorator::new('MooseX::Types::TypeDecorator', ref(Moose::Meta::TypeConstraint)) 从文件`/nfs/pdx/disks/nehalem.pde.077 调用/perl/lib64/site_perl/MooseX/Types.pm' 第 464 行
问题是我不知道如何调试正在发生的事情。单步执行代码时,执行直接从 Pattern->new 调用传递到 TypeDecorator 代码。这是在我的任何类代码执行之前发生的。我知道 Moose 正在为我创建新方法,但我不知道如何调试我看不到的代码。
我已经查看了有关 Moose 的文档,但这些都是关于如何使用它的,而不是关于幕后发生的事情。我确实通读了 Class::MOP 文档,但我不清楚这段代码的确切创建位置和时间。虽然我从所有研究中学到了一些东西,但没有一个能直接帮助我解决我的问题:)
首先,如果您对正在发生的事情有任何想法,我们将不胜感激。其次,我该如何调试这个问题?我所有常用的调试工具都让我失望了!执行直接从我对问题代码的新调用跳转,我似乎无法追踪 TypeDecorator::new 参数实际上是从哪里传递的。最后,是否有关于 Moose 究竟如何做它所做的任何好的文章?还是类::MOP?
编辑 - 这是我的类型定义。我可能会补充说,这是我第一次涉足 Moose,所以如果您发现我正在做的任何事情很奇怪,请随时指出来。
package Program::Types;
use 5.012002;
use strict;
use warnings;
our $VERSION = sprintf "2.%03d", q($Revision: 473 $) =~ /: (\d+)/;
# predeclare types
use MooseX::Types
-declare => [qw(NonemptyStr FilePath DirectoryPath FilePathThatExists DirectoryPathThatExists
TwoDigNum Pl LocalPl Pattern Program_Env Program_Whichload Program_Tpl
Program_Plist Program_Bmfc Program_Tpl_Test Program_Tpl_Flow
Program_Tpl_Flow_Item Program_Tpl_Flow_Item_Result Word)];
# import some MooseX builtin types that will be built on
use MooseX::Types::Moose qw(Str Int Object);
# types base on some objects that I use
class_type Pl, {class => 'Program::Plist::Pl'};
class_type LocalPl, {class => 'Program::Plist::LocalPl'};
class_type Pattern, {class => 'Program::Plist::Pl::Pattern'};
class_type Program_Env, {class => 'Program::Env'};
class_type Program_Whichload, {class => 'Program::Whichload'};
class_type Program_Tpl, {class => 'Program::Tpl'};
class_type Program_Tpl_Test, {class => 'Program::Tpl::Test'};
class_type Program_Tpl_Flow, {class => 'Program::Tpl::Flow'};
class_type Program_Tpl_Flow_Item, {class => 'Program::Tpl::Flow::Item'};
class_type Program_Tpl_Flow_Item_Result, {class => 'Program::Tpl::Flow::Item::Result'};
class_type Program_Plist, {class => 'Program::Plist'};
class_type Program_Bmfc, {class => 'Program::Bmfc'};
subtype Word,
as Str,
where {$_ =~ /^\w*$/};
coerce Word,
from Str,
via {$_};
subtype NonemptyStr,
as Str,
where {$_ ne ''};
coerce NonemptyStr,
from Str,
via {$_};
subtype TwoDigNum,
as Int,
where {$_ =~ /^\d\d\z/},
message {'TwoDigNum must be made of two digits.'};
coerce TwoDigNum,
from Int,
via {$_};
subtype FilePath,
as Str,
where {!($_ =~ /\0/)},
message {'FilePath cannot contain a null character'};
coerce FilePath,
from Str,
via {$_};
subtype DirectoryPath,
as Str,
where {!($_ =~ /\0/)},
message {'DirectoryPath cannot contain a null character'};
coerce DirectoryPath,
from Str,
via {$_};
subtype FilePathThatExists,
as Str,
where {(!($_ =~ /\0/) and -e $_)},
message {'FilePathThatExists must reference a path to a valid existing file.'.
"Path ($_)"};
coerce FilePathThatExists,
from Str,
via {$_};
coerce FilePathThatExists,
from FilePath,
via {$_};
subtype DirectoryPathThatExists,
as FilePath,
where {(!($_ =~ /\0/) and -d $_)},
message {'DirectoryPathThatExists must reference a path to a valid existing '.
"directory. Path ($_)"};
coerce DirectoryPathThatExists,
from Str,
via {$_};
coerce DirectoryPathThatExists,
from DirectoryPath,
via {$_};
1;
Edit2——由于明显的操作错误而被删除 :) 请注意,我在 Pattern 类中使用 BUILDARGS 而没有返回参数列表。我已在当前代码中删除了此错误,但未更改错误。
Phaylon,这是 Program::Plist::Pl 类。
package Program::Plist::Pl;
use 5.012002;
our $VERSION = sprintf "2.%03d", q($Revision: 473 $) =~ /: (\d+)/;
use Moose;
use namespace::autoclean;
use Program::Plist::Pl::Pattern;
use Program::Types qw(Pl LocalPl TwoDigNum Pattern);
use Program::Utils qw(rchomp);
use MooseX::Types::Moose qw(HashRef GlobRef Str);
use MooseX::Params::Validate;
with 'Program::Roles::PlHandler';
has 'name' => (isa => Str,
is => 'ro',
required => 1);
has 'parents' => (isa => HashRef[Pl|LocalPl],
is => 'ro',
required => 1);
has 'children' => (isa => HashRef[Pl|LocalPl],
is => 'ro');
has 'prefixes' => (isa => HashRef[TwoDigNum],
is => 'ro',
default => sub{{}});
has 'patterns' => (isa => HashRef[Pattern],
is => 'ro',
default => sub{{}});
sub _add_child {
my ($self, $obj) = (shift,
pos_validated_list(\@_, {isa => Pl|LocalPl}));
$self->{children}->{$obj->name} = $obj;
}
sub _add_pattern {
my ($self, $obj) = (shift,
pos_validated_list(\@_, {isa => Pattern}));
$self->{patterns}->{$obj->name} = $obj;
}
sub _create_pattern_obj {
$DB::single = 1;
my ($self, $name, $mask_data, $tag_data) = validated_list(\@_,
name => {isa => Str},
mask_data => {isa => Str, optional => 1},
tag_data => {isa => Str, optional => 1});
$mask_data = '' if !defined $mask_data;
my $tags = defined $tag_data ? map {$_ => 1} split(',', $tag_data) : {};
$DB::single = 1;
my $pattern_obj = Program::Plist::Pl::Pattern->new(name => $name,
mask_data => $mask_data,
tags => $tags);
$self->_add_pattern($pattern_obj);
}
sub BUILD {
my ($self, $fh) = (shift,
pos_validated_list([$_[0]->{fh}], {isa => GlobRef}));
while (<$fh>) {
# skip empty or commented lines
rchomp;
next if ((/^\s*#/) or (/^\s*$/));
# handle global plist declarations
if (my @m = /^\s*GlobalPList\s+(\w+)/) {
# creating new object and adding it to our data print STDERR
# "SELF($self)\n".join("\n",sort keys
# %Program::Plist::Pl::)."\n";
$self->_create_global_pl_obj(name => $m[0],
parents => {%{$self->parents},
$self->name => $self},
fh => $fh);
}
# handle local referenced plist declarations
elsif (@m = /^\s*PList\s+(\w+):(\w+)/) {
$self->_create_local_pl_obj(file => $m[0],
name => $m[1]);
}
# handling pattern lines
elsif (@m = /^\s*Pat\s+(\w+)\s*(\[.*\])?\s*;\s*(#([\w,])#)?\s*$/) {
$self->_create_pattern_obj(name => $m[0],
mask_data => do {defined $m[1] ? $m[1] : ''},
tag_data => do {defined $m[2] ? $m[2] : ''});
}
# handling our patlist closure
elsif (/^\s*\}/) {
last;
}
}
# need to populate our hash of child plists
for (@{$self->data}) {
if (($_->isa('Pl')) or ($_->isa('LocalPl'))) {
$self->_add_child($_);
}
}
}
__PACKAGE__->meta->make_immutable;
1;
最佳答案
问题是我相信这里。
use Program::Types qw(Pl LocalPl TwoDigNum Pattern);
您正在将一个名为 Pattern 的函数导入到您的 Program::Plist::Pl
类中。然后,您(无意中)在此处调用此函数:
my $pattern_obj = Program::Plist::Pl::Pattern->new(name => $name,
mask_data => $mask_data,
tags => $tags);
具体来说,Program::Plist::Pl::Pattern
解析为您的完全限定函数 名称,而不是您期望的类(技术上的包名称)。此函数返回一个 TypeObject,然后您可以对其调用 new()
。
注意:这正是 phaylon
在上面的评论中建议的。
除了知道您始终可以使用它的完全限定名称调用一个函数之外,确实没有办法调试它,因此永远不应该让 MooseX::Type 和有效的类名发生冲突。
如果是我,我会开始编写一个非常简单的测试用例并添加代码来复制原始文件,直到它崩溃。我可能会从调用 new 开始。然后慢慢地添加假设,直到我找到那个打破的假设。希望您在该过程中尽早添加 MooseX::Types 调用,以触发“哦,显然就是这样”的时刻。
关于Perl Moose TypeDecorator 错误。我该如何调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4621589/
我正在将旧应用程序转换为使用 Moose(和 Catalyst)并有以下问题。 如何确定用户输入的数据的 Moose 类型? 在下面的粗略示例中,我“提交”多个查询并使用下面非常基本的“验证”方法针对
从另一个 Moose 对象创建实例的正确方法是什么?在实践中,我已经看到这是通过多种方式完成的: $obj->meta->name->new() $obj->new() ## which has b
假设您有一个 Moose 类,它需要一个执行角色的属性: package MyMooseClass; use Moose; has 'a' => ( does => 'MyRole' ); 现在,我想
Moose types很棒,但有时您需要更具体。这些数据类型规则你们都知道:那个参数只能是'A' , 'B'或 'C' ,或者只是一个货币符号,或者必须符合一些正则表达式。 看看下面的例子,它有两个受
试图构建一种优雅的方式来序列化带有嵌套 Moose 对象的 Moose 对象。例子: package Asset; use Moose::Role; has 'value' => ( isa =>
我正在寻找一种在父级中设置一些辅助方法的方法 Moose类,而不是独立的实用程序类。如果可能的话,这将是一种将 Moose 糖添加到模块的更透明的方式,因为它不需要明确要求任何辅助模块(因为一切都将通
令我沮丧的是,我注意到 MooseX::Method不再维护和弃用。 包裹MooseX-Method-Signatures被宣传为替代品,但其文档说:这是 ALPHA SOFTWARE。使用风险自负。
我正在尝试创建一个对象,该对象将从网络中获取资源,并且需要记住最终找到资源的位置以及我们为其提供的原始 URL。 我不想必须两次指定 URL,也不想每次我想使用 URL 来确定我应该使用“url”属性
我有一个角色声明它需要一个方法(使用requires)。我试图通过直接在类的符号表中定义来安装该方法。但是,在某些情况下它有效,而在其他情况下则无效。 在下文中,WORKS 表示未报告任何错误,DOE
基本架构 我用 perl 构建了一个信息检索工具,使用 Moose 作为框架。 我有一个用于插件的类层次结构,其中 Base 作为插件的公共(public)基类,特定插件的访问方法从中继承(方法是 H
如何设置 Moose 只读属性特征? package AttrTrait; use Moose::Role; has 'ext' => ( isa => 'Str', is => 'ro' ); pa
我开始使用 Moose,我有以下问题。似乎我可以分配我没有在模块中指定的属性。如果我尝试访问此属性,则会出现错误消息。我怎样才能阻止模块中未指定的属性的分配?在下面的示例中,我指定了年龄,但我没有在模
package Point; use Moose; has 'x' => (isa => 'Int', is => 'rw'); has 'y' => (isa => 'Int', is => 'rw
我想要实现的是创建一个导入多个角色的 Moose 类。这是我多年来一直在做的事情,没有任何问题,尽管我目前坚持为什么下面的简单示例会产生方法名称冲突。 package logrole; use Moo
我试图找出一种方法来查看我的一个懒惰构建的属性是否已设置。我已经搜索了两个文档 驼鹿::元::属性和 类::MOP::属性 ,并看到了 get_value和 has_value方法,但它们似乎对我不起
使用 Moose 时自定义初始化某些属性的典型方法是什么? 例如,假设我将两个字符串格式的日期作为我的类的输入: has startdate => (is => 'ro', isa => 'Str'
我写了一个简单的Moose基于类称为 Document .这个类有两个属性:name和 homepage . 该类还需要提供一个名为 do_something() 的方法。它根据 homepage 从
我正在尝试使用 Perl 和 Moose 编写单例角色。我知道 MooseX::Singleton 模块可用,但是当我们的项目需要另一个 CPAN 模块时总是会遇到阻力。在尝试了这个并遇到了一些麻烦之
再次遇到 Moose 对象模型的问题。我不确定是在这里发帖还是发到“codereview”更好 - 先在这里尝试...;) 有一个Region。 该地区有一些 Spot(s)。 每个 Spot 都有
我编写了一组在 Moose 中实现的类和接口(interface)。也使用角色。我难以理解的是 Moose 特征与角色在使用和实现方面的确切差异。 Moose documentation状态: It
我是一名优秀的程序员,十分优秀!