7

我最近刚开始研究 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 被执行,我会得到错误:

“错误:未在 fooser.pl 第 6 行提供 attr1”

这是从调用者的角度来看的,因为它指向行号。fooser.pl 的第 6 行而不是 MOP.pm 的第 6 行。364.

我怎样才能在 Moose 中做到这一点?或者我在这里误解了什么?

4

1 回答 1

4

一种选择是使用MooseX::Constructor::AllErrors

该模块收集构造函数错误并将它们一起打印(默认行为是在遇到第一个错误时立即终止)。从调用者的角度来看,它具有打印的副作用。

替换你use metaclassuse MooseX::Constructor::AllErrors;,错误变为:

Attribute (attr1) is required at ./fooser.pl line 5

但是,如果您Foo->new从另一个模块(例如 Bar)内部调用并Bar->new在脚本中调用,则错误将更像:

Attribute (attr1) is required at Bar.pm line 8

...所以这不是一个完整的解决方案。

于 2010-05-02T18:48:43.783 回答