Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > perl > Depurando programas Perl

Depurando programas Perl

Todo lo que vaya encontrando útil para depurar programas y librerías escritas en este lenguaje.

Intercalando la impresión de valores

La técnica de depuración de programas más antigua y más efectiva que se conoce es la que consiste en insertar instrucciones en el fuente que impriman valores según el programa funciona.

El mayor inconveniente de esto es la eliminación de dichas instrucciones cuando el programa pasa a producción. Dada la pereza de los programadores es casi seguro que algo se queda pendiente de borrar.

Damian escribió un módulo llamado Smart::Comments que aplica esta técnica y soluciona, de un plumazo, el problema de limpiar los restos de la depuración.

El método ideado consiste incluir las instrucciones de trazado y depuración en los comentarios del programa, con una determinada síntaxis, y dejar que una herramienta externa Smart::Comments haga el trabajo sucio.

Este es un ejemplo:

    1 #!/usr/bin/perl
    2 
    3 use strict;
    4 use Carp;
    5 
    6 # use Smart::Comments;
    7 
    8 # Valores iniciales
    9 our $text = 'Hola';
   10 our $dinero = 3000.03;
   11 
   12 ### Texto: $text
   13 ### Dinero: $dinero
   14 
   15 $text =~ s/Hola/Adios/;
   16 $dinero /= 24;
   17 
   18 ### Texto: $text
   19 ### Dinero: $dinero
   20 
   21 exit (0);

y ésta es el resultado de ejecutarlo:

$ perl archive/perl/smart_comments.pl
### Texto: 'Hola'


### Dinero: '3000.03'


### Texto: 'Adios'


### Dinero: '125.00125'

$

Si queremos desactivar todo el sistema basta con comentar la línea que carga el módulo Smart::Comments y el programa funciona normalmente.

Y lo mejor de todo es que ni siquiera es necesario incluir esa línea en el fuente del programa. Supongamos que éste va a ir después a producción, y no deseamos vernos en la necesidad de modificar un programa en los directorios del sistema. Siempre podemos invocar el programa de esta manera:

$ perl -MSmart::Comments nuestro-programa.pl

y no tendremos que tocar el programa para nada. Existen excepciones como explico en la página SmartComments a tener en cuenta cuando se emplea en programas complejos.

Depurando módulos de terceros

El depurador de programas Perl tiene un espacio de nombres propio y en él están definidas algunas variables que pueden modificar su comportamiento. La mejor referencia sigue siendo la fuente: perldebug y perldebtut.

La técnica para depurar módulos de terceros consiste en:

  1. Crear un directorio especial, que podemos llamar libext/
  2. Copiar en ese directorio el módulo que necesitamos examinar, con la misma estructura que tiene en la instalación del sistema:

    $ mkdir libext/IkiWiki/Plugin
    $ cp /usr/share/perl5/IkiWiki/Plugin/inline.pm libext/IkiWiki/Plugin/
    
  3. Ahora podemos modificar el archivo e incluir la siguiente línea en el punto en que queremos que el depurador detenga la ejecución y nos dé el control:

    $DB::trace = 1;
    
  4. Y ejecutamos nuestro programa con el parámetro extra:

    $ perl -d -Ilibext -Ilib nuestro_programa.pl
    

    De manera que cuando el programa use el módulo IkiWiki::Plugin::inline se cargue primero nuestra copia local, y al alcanzar el punto en el que dicha variable cambia, el depurador nos cederá el control. Si el valor es 1, el depurador entenderá una instrucción s (single step), y si el valor es 2, se ejecutará una instrucción n (next).

Otro truco procedente de la documentación es situar un punto de ruptura justo en la carga del módulo que queremos:

DB<7> b load /usr/share/perl5/IkiWiki/Plugin/inline.pm

y reiniciar la ejecución con la órden R (restart). La ruta del módulo, como puede verse, debe ser absoluta.

Limitando los volcados de datos

Vía el diario de jplindstorm recojo unos cuantos trucos para limitar la cantidad de información que a veces tenemos que soportar en el desarrollo.

  • En el módulo Data::Dumper podemos usar:

    local $Data::Dumper::Maxdepth = 3;
    

    antes de emplearlo en algo.

  • En el depurador tenemos lo siguiente:

    • La instrucción x se puede limitar con:

      x [maxdepth] expression
      
    • O podemos emplear la opción:

      o dumpDepth=3
      
    • Y cuando utilizamos la orden r para retornar de la subrutina en la que nos encontramos, y no nos interesa el valor de retorno de la misma, sólo salir, podemos usar:

      o PrintRet=0
      

    Si queremos conservar estos cambios permanentemente podemos incluirlos en el archivo .perldb del directorio activo ó de nuestro directorio raíz:

    DB::parse_options("dumpDepth=3");
    DB::parse_options("PrintRet=0");