我最近刚刚开始使用Moose,它不仅是一个很好的OO框架,而且还用于学习新的OO概念。我想做的一件事就是在对象创建期间从调用者的角度进行错误报告。我看到Moose有模块Moose :: Error :: Croak,它告诉Moose通过croak调用覆盖默认的错误报告。我用它但它似乎没有帮助
驼鹿代码 - Foo.pm
package Foo;
use metaclass (
metaclass => 'Moose::Meta::Class',
error_class => 'Moose::Error::Croak',
);
use Moose;
has 'attr1' => (
is => 'rw',
isa => 'Str',
required => '1',
);
no Moose;
1;
驼鹿代码 - fooser.pl
#!/usr/bin/perl
use strict;
use warnings;
use Foo;
my $foobj = Foo->new();
此操作失败并显示错误: /usr/local/lib/perl/5.8.8/Class/MOP/Class.pm第364行需要属性(attr1)
如果没有使用Moose :: Error :: Croak,那么比实际的堆栈跟踪简洁。但它不会从调用者的角度报告它。如果这是一个Perl 5 OO代码,我将Foo.pm作为:
package Foo;
use strict;
use warnings;
use Carp;
sub new {
my ($class, %args) = @_;
my $self = {};
if (! exists $args{'attr1'}) {
croak "ERR: did not provide attr1";
}
$self->{'attr1'} = $args{attr1};
bless $self, $class;
return $self;
}
1;
如果fooser.pl被执行,我会得到错误:
“ERR:没有在fooser.pl第6行提供attr1”
这是从调用者的角度来看,因为它指向行号。 6个fooser.pl而不是MOP.pm的行号。 364。
我怎么能在穆斯这样做?或者我在这里误解了什么?
答案 0 :(得分:4)
一种选择是使用MooseX::Constructor::AllErrors。
此模块收集构造函数错误并将它们全部打印在一起(默认行为是在遇到第一个错误时立即死亡)。从呼叫者的角度来看,它具有打印的副作用。
将use metaclass
替换为use MooseX::Constructor::AllErrors;
,错误变为:
Attribute (attr1) is required at ./fooser.pl line 5
但是,如果您从其他模块(例如Bar)内部调用Foo->new
并在脚本中调用Bar->new
,则错误更像是:
Attribute (attr1) is required at Bar.pm line 8
......所以这不是一个完整的解决方案。