2010-05-19 15 views
14

estoy aprendiendo Perl, y en muchos de los ejemplos que veo errores se manejan como esto¿Cuáles son las mejores prácticas para el manejo de errores en Perl?

open FILE, "file.txt" or die $!; 

Es die en medio de un guión realmente la mejor manera de tratar con un error?

+6

Para ver las discusiones sobre las excepciones de Perl, consulte [¿Qué hay de malo en las excepciones en Perl?] (Http://stackoverflow.com/questions/2165161/whats-broken-about-exceptions-in-perl), [¿Utiliza una clase de excepción en sus programas Perl? ¿Por qué o por qué no?] (Http://stackoverflow.com/questions/2439966/do-you-use-an-exception-class-in-your-perl-programs-why-or-why-not), y [ Manejo de excepciones orientado a objetos en Perl: ¿vale la pena?] (Http://stackoverflow.com/questions/503189/object-oriented-exception-handling-in-perl-is-it-worth-it) – Ether

Respuesta

21

Si die es apropiado en el medio de la secuencia de comandos realmente depende de lo que está haciendo. Si solo son decenas de líneas, está bien. Una pequeña herramienta con un par de cientos de líneas, luego considere confesar (ver abajo). Si se trata de un gran sistema orientado a objetos con muchas clases y código interconectado, entonces tal vez un objeto de excepción sería mejor.

confesar en el paquete Carp:
A menudo, el error que provocó la muerte no está en la línea que muere informes. Reemplazar el dado con confess (ver paquete Carp) dará el rastro de la pila (cómo llegamos a esta línea) que ayuda mucho en la depuración.

Para manejar excepciones de construcciones Perl, me gusta usar autodie. Captura fallas de open y otras llamadas al sistema y generará excepciones para usted, sin tener que hacer el bit or die. Estas excepciones se pueden capturar con un eval { }, o mejor aún, usando Try::Tiny.

+4

+1 por sugerir 'autodie'. –

+1

Siempre he pensado que deberían llamarlo 'autoOrDie' :) – friedo

+0

@friedo Se parecería mucho a' authorDie' :) – dolmen

3

El enfoque más moderno es utilizar la biblioteca estándar de Carp.

use Carp; 
my $fh; 
open $fh, '<', "file.txt" or confess($!); 

La principal ventaja es que proporciona un seguimiento de la pila al morir.

+0

Bien , croak no da un rastro de pila a menos que establezcas otras cosas de Carpa. –

+0

@brian: whoop, corregido. –

+1

Gracias! No sabía sobre Carpas ... pero ¿desde cuándo croan las Carpas? – SystematicFrank

0

utilizo mueren pero lo envuelve en bloques eval por el control de la gestión de errores:

my $status = eval 
{ 
    # Some code... 
}; 

Si el 'eval' falla:

  1. $status habrá definido.
  2. [email protected] se ajustará a cualquier mensaje de error se produce (o el contenido de un die)

Si el 'eval' tiene éxito:

  1. $status será el último valor devuelto de la bloquear.
  2. [email protected] se establecerá en ''.
+5

Hay un montón de problemas con 'eval {}' que necesitan soluciones poco claras. Use Try :: Tiny en su lugar. Cubre todo el repetitivo nocivo en un paquete limpio y fácil de usar. – daotoad

+1

Hay un montón de problemas con 'eval {}' que necesitan soluciones poco claras ... si le importa identificar el error. Si va a realizar la misma acción independientemente de su causa, un simple bloque 'eval' funciona bien. Pero sí, use 'Try :: Tiny' en todos los demás casos. –

+0

Lo intentaré la próxima vez que escriba algo de Perl. Utilizo esta forma para falsificar un try-catch (agregando un cheque de $ @ después del bloque eval.) Gracias por los consejos. –

12

Como utilizo Log::Log4perl en casi todas partes, uso $logger->logdie en lugar de die. Y si desea tener más control sobre sus excepciones, considere Exception::Class.

Es mejor detectar sus excepciones con Try::Tiny (consulte su documentación por qué).

6

A menos que tengas una idea más específica, entonces quieres morir cuando suceden cosas inesperadas.

  • muriendo por la falta de abrir un archivo y dar el nombre del archivo es mejor que el sistema le dice que no puede leer o escribir en un indefinido en el anonimato.

  • Si está hablando de un "script", en general, está hablando de un código bastante simple. No capas que necesitan coordinación (no usualmente). En un Perl Módulo, existe la idea de que no posee el entorno de ejecución, por lo que el software principal se preocupa y capta las cosas en una evaluación, O realmente no importa y morir estaría bien. Sin embargo, uno debería probar con un poco más de robustez como módulo y simplemente pasar undefs o algo así.

  • Puede atrapar lo que muere (o croa) en un bloque eval. Y puede hacer su manejo más específico allí.

  • ¡Pero si quiere inspeccionar $! luego escribe ese código, y tendrás una resolución más específica.

  • Eche un vistazo al estándar casi universal de usar strict. Ese es el código que muere en sintaxis cuestionable, en lugar de dejar que continúes.

Así que creo que la idea general es: sí, DIE menos que tenga una mejor idea de cómo se deben manejar las cosas. Si le da suficiente previsión, puede perdonarle una o dos veces que no muera, porque sabe que no necesita hacerlo.

Cuestiones relacionadas