12

考虑这个简单的类:

package Foo;
use Moose;
has foo => ( is => 'rw', isa => 'Int' );

然后这段代码:

use Try::Tiny;
use Foo;
my $f = try {
    Foo->new( foo => 'Not an Int' );
}
catch {
    warn $_;
};

代码以关于类型约束失败的大错误消息而终止。

我希望能够提取失败的属性(foo)、原因是什么(失败的类型约束)以及传递的值是(Not an Int),而无需解析错误字符串来获取信息。

像这样的东西:

catch {
    if( $_->isa( 'MooseX::Exception::TypeConstraint' ) ) {
         my $attrib = $_->attribute;
         my $type   = $_->type;
         my $value  = $_->bad_value;

         warn "'$value' is an illegal value for '$attrib'.  It should be a $type\n"; 
    }
    else {
         warn $_;
    }
};

这可能吗?有没有一个 MooseX 发行版可以做到这一点?更好的是,是否有一些我错过的 Moose 功能可以使这成为可能?

更新:我对类型约束特别感兴趣,但其他 Moose 错误也会非常好。我也知道我可以用die. 因此,在我编写的代码中构造异常相对容易。

4

3 回答 3

4

我自己没有尝试过,但我认为MooseX::Error::Exception::Class可能是您正在寻找的。

于 2010-02-11T05:37:20.203 回答
3

查看MooseX::Throwable,它替换error_class了元类中的值。然而,代码看起来有点旧(metaroles 现在确实支持错误类角色),但当前的方法看起来仍然可以工作。

于 2010-02-11T00:42:04.230 回答
1

大约一年前我有同样的问题,并在#moose IRC 频道问过。答案是 Moose 并不真正支持结构化异常......但是。

普遍认为 Moose 的一个缺点应该被修复,但是在各处引入异常的任务是乏味的,并且还没有(afaik)被执行。

MooseX::Error::Exception::Class 中的方法非常脆弱,因为它基于解析来自 Moose 的消息。

由于您无法真正从 Moose 获得可靠的结构化异常,因此请考虑在设置新值时使用自省来一一测试您的每个类型约束。有时这是一种可行的方法。

顺便说一句:请注意,Moose 处理复合约束的方式存在一个令人讨厌的错误

于 2011-06-16T01:05:18.583 回答