Как использовать AutoDie с не встроенными? - PullRequest
7 голосов
/ 17 марта 2011

Документация autodie намекает на то, что его можно использовать для других функций, кроме тех встроенных, которые он может обрабатывать по умолчанию, но нет четких примеров, как это сделать в нем.

В частности, яхотел бы использовать его для модуля Imager.Многие функции и методы этого могут потерпеть неудачу, и я бы предпочел, чтобы это не означало, что мой код будет полон or die Imager|$image->errstr; фраз по всему.

Конечно, если есть другой способ, чемиспользуя autodie, я бы тоже заинтересовался этим.

Ответы [ 3 ]

4 голосов
/ 17 марта 2011

autodie работает только с функциями, а не с методами. Это потому, что он имеет лексическую область видимости, а поиск метода не может быть лексической областью. autodie :: hints объясняет, как сообщить autodie о пользовательских функциях, но это ничего не даст для методов.

Я не знаю ни одного способа получить поведение, похожее на autodie, для методов, если только модуль не имеет встроенного (например, DBI 'RaiseError).

У вас может быть подпрограмма для проверки, но она не сохранит столько кода, так как вам все равно придется передать ему правильный объект или класс для вызова errstr.

2 голосов
/ 17 марта 2011
1 голос
/ 18 марта 2011

Вот альтернативный метод, который работает с методами:

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 ##'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...