Moose::Error::Croak 错误报告不是从调用者的角度来看的

发布于 2024-08-30 21:23:04 字数 1252 浏览 6 评论 0原文

我最近刚刚开始使用 Moose,它是一个很棒的 OO 框架,不仅可以使用,还可以学习新的 OO 概念。我想做的一件事是在对象创建期间从调用者的角度进行错误报告。我看到 Moose 有 Moose::Error::Croak 模块,它告诉 Moose 通过 croak 调用覆盖默认的错误报告。我使用了它,但它似乎没有帮助

Moose 代码 - 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;

Moose 代码 - 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: did not Provide attr1 at fooser.pl line 6”,

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

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

I just recently started out on Moose and its a great OO framework not only to use but also to learn new OO concepts. One of the things I wanted to do was to do error reporting from perspective of caller during object creation. I saw that Moose has the module Moose::Error::Croak which tells Moose to override the default error reporting by croak call. I used it but it did not seem to help

Moose code - 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;

Moose code - fooser.pl

#!/usr/bin/perl
use strict;
use warnings;
use Foo;
my $foobj = Foo->new();

This fails with error:
Attribute (attr1) is required at /usr/local/lib/perl/5.8.8/Class/MOP/Class.pm line 364

which is terse than the actual stack trace if Moose::Error::Croak is not used. But it does not report it from perspective of caller. If this were a Perl 5 OO code and I had Foo.pm as:

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;

And if fooser.pl was executed I would have got the error:

"ERR: did not provide attr1 at fooser.pl line 6"

which is from the perspective of the caller as it points to line no. 6 of fooser.pl rather than MOP.pm's line no. 364.

How can I do this in Moose? Or am I misunderstanding something here?

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

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

发布评论

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

评论(1

同展鸳鸯锦 2024-09-06 21:23:04

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

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

将您的 use metaclass 替换为 use 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

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

One option is to use MooseX::Constructor::AllErrors.

This module collects constructor errors and prints them all together (default behaviour is to die as soon as the first error is encountered). It has a side-effect of printing from the caller's perspective.

Replace your use metaclass with use MooseX::Constructor::AllErrors; and the error becomes:

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

However, if you call Foo->new from inside another module (e.g. Bar) and call Bar->new in your script, the error would be more like:

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

...so it's not a complete solution.

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