autodie 文档提示可以将它用于其他功能,而不是默认情况下可以处理的内置功能,但没有明确的示例如何在其中执行此操作。
具体来说,我想将它用于 Imager 模块。很多功能和方法都可能失败,如果这不意味着我的代码会到处都是or die Imager|$image->errstr;
短语,我会更喜欢。
当然,如果除了使用 autodie 之外还有其他方法可以实现这一点,我也会对此感兴趣。
autodie仅适用于函数,而不适用于方法。这是因为它是词法作用域的,而方法查找不能是词法作用域的。 autodie::hints解释了如何告诉 autodie 用户定义的函数,但这对方法没有任何作用。
我不知道有什么方法可以让方法获得类似自动死亡的行为,除非模块内置了(例如DBI的RaiseError
)。
您可以有一个子例程来进行检查,但它不会节省那么多代码,因为您仍然必须将正确的对象或类传递给它才能调用errstr
。
这是一种适用于方法的替代技术:
package SafeCall;
use Carp ();
sub AUTOLOAD {
my ($method) = our $AUTOLOAD =~ /([^:']+)$/; #'
unshift @_, my $obj = ${shift @_};
my $code = $obj->can($method)
or Carp::croak "no method '$method' on $obj";
&$code or Carp::croak $obj->can('errstr')
? $obj->errstr
: "calling $method on $obj failed"
}
并使用它:
package Image;
sub new {bless {here => 'ok', also => 'can be looked up'}};
sub fails {$_[0]{not_here}}
sub succeeds {$_[0]{here}}
sub lookup {$_[0]{$_[1]}}
sub errstr {'an error occurred'}
package main;
use 5.010; # for say()
my $safe = sub {bless \$_[0] => 'SafeCall'};
# storing the constructor in the scalar $safe allows $safe to be used
# as a method: $obj->$safe->method
my $img = Image->new;
say $img->$safe->succeeds; # prints 'ok'
say $safe->($img)->succeeds; # or call this way (also prints 'ok')
say $img->$safe->lookup('also'); # prints 'can be looked up'
say $img->$safe->fails; # dies with 'an error occurred at file.pl line ##'