2011-03-17 29 views
7

La documentación de autodie indica que es posible utilizarla para otras funciones diferentes a las integradas que puede manejar de forma predeterminada, pero no hay ejemplos claros de cómo hacer eso en ella.¿Cómo utilizar la autodie con no incorporados?

Específicamente me gustaría usarlo para el módulo Imager. Muchas de las funciones y métodos de eso pueden fallar, y yo preferiría que eso no significara que mi código estará lleno de frases or die Imager|$image->errstr; en todas partes.

Por supuesto, si hay otra forma de usar autodie para lograr eso, también me interesaría.

Respuesta

4

autodie sólo funciona con las funciones, no métodos. Esto se debe a que tiene un alcance léxico, y la búsqueda de métodos no puede tener un alcance léxico. autodie::hints explica cómo decirle a la autodie sobre las funciones definidas por el usuario, pero eso no servirá para los métodos.

No conozco ninguna forma de obtener un comportamiento parecido a la autodie para los métodos, a menos que el módulo tenga eso incorporado (por ejemplo, DBI 's RaiseError).

Puede tener una subrutina para hacer el control, pero no guardará tanto código, ya que aún tendrá que pasarle el objeto o la clase correcta para llamar al errstr.

2
+0

Gracias. Si lo entendí correctamente, solo necesito poner los nombres de las funciones en la lista de argumentos para 'use autodie' si señalan la falla en uno de los comportamientos predeterminados que figuran en la introducción. Pero todavía no parece funcionar. Imager es principalmente OO. ¿Hay algo especial que deba hacer para que Autodie funcione con métodos? –

1

Aquí es una técnica alternativa que funciona con métodos:

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" 
    } 

Y utilizarlo:

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