如果 Moose 构建器方法失败,我该怎么办? [英] What should I do if a Moose builder method fails?

查看:55
本文介绍了如果 Moose 构建器方法失败,我该怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

处理构建器方法失败的最佳方法是什么?

What is the best way to handle a failure in a builder method?

例如:

package MyObj;
use Moose;
use IO::File;

has => 'file_name'   ( is => 'ro', isa => 'Str',      required   =>1  );
has => 'file_handle' ( is => 'ro', isa => 'IO::File', lazy_build => 1 );

sub _build_file_handle {
    my $self = shift;
    my $fh = IO::File->new( $self->file_name, '<' );

    return $fh;
}

如果_build_file_handle 无法获取句柄,构建器将返回undef,这将失败类型约束.

If the _build_file_handle fails to get a handle, the builder will return undef, which fails the type constraint.

我可以在 file_handle 类型约束中使用联合,以便它接受 undef 作为有效值.但是,谓词 has_file_handle 将返回 true,即使值为 undef.

I could use a union in the file_handle type constraint, so that it will accept an undef as a valid value. But then, the predicate has_file_handle will return true, even when the value is undef.

有没有办法发出构建器失败的信号,并且属性应该保持清除状态?

Is there a way to signal that the builder failed, and the attribute should remain cleared?

推荐答案

最佳"是主观的,但您必须决定哪个在您的代码中更有意义:

"Best" is subjective, but you'll have to decide which makes more sense in your code:

  1. 如果您可以在文件句柄构建失败时继续执行代码(即它是可恢复的情况),构建器应返回 undef 并将类型约束设置为 'Maybe[IO::File]'.这意味着您还必须在使用该属性时检查该属性的定义.您还可以检查此属性是否在 BUILD 中正确构建,并选择在那时采取进一步行动(如 Friedo 在他的评论中提到的),例如如果它是 undef,则调用 clear_file_handle(因为构建器将始终为该属性分配一个值,假设它当然不会消亡).

  1. if you can continue on in your code when the filehandle fails to build (i.e. it is a recoverable condition), the builder should return undef and set the type constraint to 'Maybe[IO::File]'. That means you'll also have to check for definedness on that attribute whenever using it. You could also check if this attribute got built properly in BUILD, and choose to take further action at that point (as friedo alluded to in his comment), e.g. calling clear_file_handle if it is undef (since a builder will always assign a value to the attribute, assuming it doesn't die of course).

否则,让构建器失败,或者通过显式抛出异常(您可以选择追上更高),或者简单地返回 undef 并让类型约束失败.无论哪种方式,您的代码都会死亡;您只需选择它如何消亡以及堆栈跟踪的数量.:)

otherwise, let the builder fail, either by explicitly throwing an exception (which you can opt to catch higher up), or simply returning undef and letting the type constraint fail. Either way your code will die; you just get a choice of how it dies and how voluminous the stack trace is. :)

附注.您可能还想查看 Moose 内部使用的 Try::Tiny,并且基本上只是* do eval { blah } or die ... 习语的包装.

PS. You may also want to look at Try::Tiny, which Moose uses internally, and is basically just a wrapper for* the do eval { blah } or die ... idiom.

*但是做得对!并且以一种很酷的方式!(我似乎听到很多来自#moose 的耳语.)

这篇关于如果 Moose 构建器方法失败,我该怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆