• Publicidad

Manejo errores

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Manejo errores

Notapor davidferrero » 2009-08-11 05:39 @277

Buenas, mi consulta es la siguiente: estoy intentando manejar errores en Perl, pero me encuentro con un problema.

Todo lo que veo es que si encuentra el error, por ejemplo
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open FILE, $fich or die "$@"...
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
para en caso de error terminar la ejecución del programa.

Viendo el tutorial encuentro que puedo llamar a una función pero igualmente el final es salir del programa; si utilizo la función eval() tengo el mismo resultado.

¿Existe algún método que en vez de acabar con el proceso, por ejemplo, salte la ejecución de esa función, es decir, si hago
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub fun(){open FILE, $fich ...}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
trate el error pero solo salga de esa función?

Gracias de antemano por atender y responder mis dudas.
davidferrero
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2009-07-29 03:12 @175

Publicidad

Re: Manejo errores

Notapor kidd » 2009-08-11 08:05 @378

Bueno, si quieres salir de la función si no pudiste abrir un fichero, simplemente haz lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open FILE, $fich or return;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Re: Manejo errores

Notapor explorer » 2009-08-11 08:07 @380

Un tema interesante, el de los errores. Se habló algo en la última YAPC::EU::2009. Incluso Larry Walll nos dió un divertido repaso sobre los mensajes de error de los sistemas de antaño.

Tienes algo de información sobre la captura de errores, en la documentación de eval().

Aquí tienes un ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. print "Antecedente...\n";
  7.  
  8. funcion_que_abre_fichero_inexistente();
  9.  
  10. print "Seguimos...\n";
  11.  
  12. sub funcion_que_abre_fichero_inexistente {
  13.     my $linea;
  14.  
  15.     eval {
  16.         open my $FICHERO, q[<], 'Fichero_inexistente' or die "ERROR: No encuento al Fichero_inexistente\n";
  17.         $linea = <$FICHERO>;
  18.         close $FICHERO;
  19.     };
  20.  
  21.     warn $@ if $@;
  22.  
  23.     return $linea;
  24. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La salida es
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Antecedente...
ERROR: No encuento al Fichero_inexistente
Seguimos...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

El die() ha capturado el error, pero la aplicación sigue funcionando.
En caso de no poner die(), la salida hubiera sido esta, por acción del warn():
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Antecedente...
readline() on closed filehandle $FICHERO at ./kk.pl line 17 (#1)
    (W closed) The filehandle you're reading from got itself closed sometime
    before now.  Check your control flow.

Seguimos...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
que es la descripción del error por haber intentado leer un fichero que aún no hemos abierto (línea 17).

Teniendo en cuenta que tanto open() como close() como cualquier otra operación de entrada y salida pueden provocar algún tipo de error, lo normal es usar el módulo Fatal, que permite elevar una excepción en caso de que alguna de las funciones indicadas devuelva un valor undef, indicación de que algo fue mal:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use Fatal qw(open close);
  7.  
  8. print "Antecedente...\n";
  9.  
  10. funcion_que_abre_fichero_inexistente();
  11.  
  12. print "Seguimos...\n";
  13.  
  14. sub funcion_que_abre_fichero_inexistente {
  15.     my $linea;
  16.  
  17.     if (open my $FICHERO, q[<], 'Fichero_inexistente') {
  18.         warn $! if $!;
  19.         $linea = <$FICHERO>;
  20.         close $FICHERO;
  21.     }
  22.  
  23.     return $linea;
  24. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La salida es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Antecedente...
Uncaught exception from user code:
        Can't open(GLOB(0x816e888), <, Fichero_inexistente): No existe el fichero o el directorio at (eval 2) line 3
        main::__ANON__('GLOB(0x816e888)', '<', 'Fichero_inexistente') called at ./kk.pl line 17
        main::funcion_que_abre_fichero_inexistente() called at ./kk.pl line 10
 at (eval 2) line 3
        main::__ANON__('GLOB(0x816e888)', '<', 'Fichero_inexistente') called at ./kk.pl line 17
        main::funcion_que_abre_fichero_inexistente() called at ./kk.pl line 10
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
¡Boom!
Naturalmente, se puede capturar, con eval():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use Fatal qw(open close);
  7.  
  8. print "Antecedente...\n";
  9.  
  10. funcion_que_abre_fichero_inexistente();
  11.  
  12. print "Seguimos...\n";
  13.  
  14. sub funcion_que_abre_fichero_inexistente {
  15.     my $linea;
  16.  
  17.     eval {
  18.         open my $FICHERO, q[<], 'Fichero_inexistente';
  19.         $linea = <$FICHERO>;
  20.         close $FICHERO;
  21.     };
  22.  
  23.     warn $! if $!;
  24.  
  25.     return $linea;
  26. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
cuya salida es
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Antecedente...
Descriptor de fichero erróneo at ./kk.pl line 23.
Seguimos...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Vamos, que Fatal solo nos abrevia el no tener que poner die() en todas las funciones, de esta manera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        open my $FICHERO, q[<], 'Fichero_inexistente' or die;
        $linea = <$FICHERO>                           or die;
        close $FICHERO                                or die;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
ya que todas esas operaciones pueden fallar. Pero necesitamos seguir capturándolas para tratar los errores, algo que podemos hacer con eval() y con módulos como el Error, que remeda algunas de las funciones que vemos en otros lenguajes, como try() y catch().

En la última YAPC::EU::2009, Paul Fenwick nos recomendó usar su módulo autodie y autodie::exception (sí, el sombrero pirata lo llevó a la conferencia).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. print "Antecedente...\n";
  7.  
  8. funcion_que_abre_fichero_inexistente();
  9.  
  10. print "Seguimos...\n";
  11.  
  12. sub funcion_que_abre_fichero_inexistente {
  13.     my $linea;
  14.  
  15.     eval {
  16.         use autodie;
  17.  
  18.         open my $FICHERO, q[<], 'Fichero_inexistente';
  19.         $linea = <$FICHERO>;
  20.         close $FICHERO;
  21.     };
  22.  
  23.     if (my $E = $@) {
  24.         print "Ooops!  ",$E->caller," tiene problemas: $@\n";
  25.     }
  26.  
  27.     return $linea;
  28. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
con lo que sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Antecedente...
Ooops!  main::funcion_que_abre_fichero_inexistente tiene problemas: Can't open 'Fichero_inexistente' for reading: 'No existe el fichero o el directorio' at ./kk.pl line 18

Seguimos...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Este módulo da toda la función relativa al fallo que ha ocurrido. Y así puedes decidir qué hacer. Aunque...

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
        bIlujDI' yIchegh()Qo'; yIHegh()!

        It is better to die() than to return() in failure.

                -- Klingon programming proverb.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

(Paul nos dio otra conferencia sobre Perl/Klingon y el control de errores con autodie, vestido con su uniforme de la flota estelar :) )
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Manejo errores

Notapor davidferrero » 2009-08-12 02:37 @150

Vale, eso es lo que necesitaba, me gusta el proverbio, en este caso la opción es continuar en fallo porque necesito monitorizar, y si existe algún error en alguna función no quiero que muera el proceso entero sino que marque el error, lo guarde y continúe con el resto de funciones; pero lo tendré en cuenta. Gracias por todo.
Última edición por explorer el 2009-08-12 03:22 @182, editado 1 vez en total
davidferrero
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2009-07-29 03:12 @175


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 18 invitados

cron