【问题标题】:How to use autodie with non-builtins?如何将 autodie 与非内置函数一起使用?
【发布时间】:2011-03-17 10:12:51
【问题描述】:

autodie 文档提示,除了默认情况下可以处理的内置函数之外,还可以将其用于其他功能,但其中没有明确的示例。

具体来说,我想将它用于 Imager 模块。很多函数和方法都可能失败,如果这不意味着我的代码会到处都是or die Imager|$image->errstr; 短语,我会更愿意。

当然,如果除了使用 autodie 之外还有其他方法可以实现这一点,我也会对此感兴趣。

【问题讨论】:

    标签: perl autodie


    【解决方案1】:

    autodie 仅适用于函数,不适用于方法。这是因为它是词法作用域的,而方法查找不能是词法作用域的。 autodie::hints 解释了如何告诉 autodie 用户定义的函数,但这对方法没有任何作用。

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

    您可以有一个子例程来进行检查,但它不会节省那么多代码,因为您仍然需要将正确的对象或类传递给它才能调用errstr

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 谢谢。如果我理解正确,我只需要将函数的名称放入use autodie 的参数列表中,前提是它们通过介绍中列出的默认行为之一发出失败信号。但它似乎仍然不起作用。 Imager主要是OO。为了使 autodie 使用方法,我需要做些什么特别的事情吗?
      【解决方案3】:

      这是一种与方法一起使用的替代技术:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-15
        • 1970-01-01
        • 2019-11-21
        相关资源
        最近更新 更多