如何使用autodie与非内置?

时间:2011-03-17 10:12:52

标签: perl autodie

autodie文档暗示可以将它用于除默认情况下可以处理的内置函数之外的其他函数,但是没有明确的示例如何在其中执行此操作。

具体来说我想将它用于Imager模块。许多功能和方法可能会失败,我希望如果这并不意味着我的代码将遍布or die Imager|$image->errstr;个短语。

当然,如果有另一种方法而不是使用autodie来实现这一点,我也会对此感兴趣。

3 个答案:

答案 0 :(得分:4)

autodie仅适用于函数,而不适用于方法。这是因为它是词法范围的,并且方法查找不能在词法范围内。 autodie::hints解释了如何告诉autodie有关用户定义的函数,但这对方法无效。

我不知道有什么方法可以获得方法的类似autodie的行为,除非模块具有内置的(例如DBIRaiseError)。

你可以有一个子程序来进行检查,但它不会保存所有那么多代码,因为你仍然需要传递正确的对象或类来调用errstr

答案 1 :(得分:2)

请参阅autodie::hints

答案 2 :(得分:1)

以下是一种可与方法配合使用的替代技术:

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 ##'