Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > perl > cpan > Smart::Comments

Smart::Comments

La librería de comentarios inteligentes es de tipo filtro de código y permite incluir directivas de depuración y trazado en los comentarios de un programa, de manera que dota a estos de inteligencia en más de un sentido según palabras del autor Damian Conway.

Lo cierto es que dado que se trata de comentarios en un fuente, conservarlos es siempre algo inteligente. ;-)

Uso

    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);

Descripción

El módulo actúa sobre cierto tipo de comentarios, generalmente aquellos que comienzan por tres caracteres almohadilla (###) consecutivos. El resto de la línea es interpretado por el módulo y proporciona una determina información a la salida estándar de errores, ó efectúa alguna acción dramática como detener el programa si no se cumplen determinadas condiciones (Assert).

Para cambiar el nivel de inteligencia de los comentarios se puede cargar el módulo y pasarle uno o más marcadores sobre los que queremos que actúe:

    1 use Smart::Comments '####', '#####';

Esto es útil para, por ejemplo, seleccionar barras de progreso de comentarios de depuración, en caso de que deseemos mostrar sólo las primeras.

    1 ##### Comenzamos aquí ...
    2 
    3 for (@values) {     ### Progress: 0 .. 100
    4     do_stuff();
    5 }

Depurando mediante comentarios

El módulo acepta los siguientes casos:

Label : Expression

Label es cualquier texto hasta los dos puntos y expression es cualquier expresión Perl, incluyendo una simple variable.

Cuando se activa se muestra la etiqueta seguida del resultado de la evaluación de la expresión.

    1     ### Expected: 2 * $prediction
    2     ##      Got: $result

Expression

Similar al anterior sólo que no incluye un texto, por lo que se muestra la expresión literalmente, el carácter dos puntos y el resultado de la expresión cuando este comentario está activo.

Text ...

Un texto finalizado por tres puntos y que sirve como comentario de depuración (ó trazado) ya que es sólo eso lo que se va a mostrar.

Eso sí, dentro de este texto es posible utilizar dos secuencias especiales, encerradas entre símbolos de mayor y menor y que tienen sinónimos

  • now | time | when

    Expande a la hora y fecha en el momento de ejecutarse

  • here | line | loc | place | where

    Expande al nombre del módulo Perl y al número de línea

Ejemplo para ilustrar esto:

 ### [<now>] Acquiring data...

 ### Acquiring data at <loc>...

que expande a:

 ### [Fri Nov 18 15:11:15 EST 2005] Acquiring data...

 ### Acquiring data at "demo.pl", line 7...

naturalmente pueden utilizarse las dos. Y eso resulta también bastante útil para procesos por lotes donde se quiera disponer de un trazado de ejecución automágico.

Chequeos y aseveraciones

También es posible utilizar la expresión Perl como comprobante (ó garante) de que hemos alcanzado determinado punto en la ejecución de un programa. Smart::Comments dispone de varias directivas para este fin.

Chequeos

Utilizando alguna de las siguientes palabras clave: check, verify ó confirm creamos una comprobación automática sobre la expresión en contexto booleano. Si el valor resultante es falso (esto es, que falla) se emite un aviso (empleando warn) en el que se informa de la expresión que ha fallado, el por qué y los diferentes valores implicados en el momento del fallo.

Un ejemplo sería:

 ### require: $min < $result && $result < $max

que daría como resultado un aviso de este tipo:

    ### $min < $result && $result < $max was not true at demo.pl line 86.
    ###     $min was: 7
    ###     $result was: 1000004
    ###     $max was: 99

Aseveraciones

Es el mismo mecanismo que para los chequeos, pero emitiendo una excepción en el programa y parando la ejecución si nadie la atrapa. Es decir, utiliza die en lugar de warn.

Las palabras clave en este caso son: require, assert, ensure e insist.

Barras de progreso

PENDIENTE DE COMPLETAR

Experiencias

Uso en desarrollo

Una de las primeas cosas a advertir sobre este módulo es que actúa únicamente sobre aquél que lo carga. No es, como tal vez pueda entenderse, una especie de infección viral que actuá sobre todos y cada uno de los módulos que conforman un programa.

Sí lo hace con el módulo principal si cargamos esta librería en el intérprete Perl mediante el parámetro -M, pero nada más; no recorre el resto de los módulos dotando de inteligencia a los comentarios allí donde los encuentra.

Esto plantea un problema cuando queremos utilizarlo en una gran aplicación, compuesta de muchas librerías de nuestra manufactura, y donde necesitamos que esté activo en varias de ellas. A mí se me ha ocurrido una primera solución parcial para cuando necesitamos esta característica en un paquete concreto:

    1 package MyPackage;
    2 
    3 BEGIN {
    4     (my $package = __PACKAGE__) =~ s{::}{_}g;
    5 
    6     if (defined($ENV{$package}) and
    7         $ENV{$package}) eq 'Smart::Comments') {
    8         require "Smart::Comments";
    9         Smart::Comments->import();
   10     }
   11 }

Si se añade el código anterior a cualquier paquete, éste primero transformará el nombre del mismo cambiándo todos los separadores Perl :: por subrayados, y luego comprobará que exista una variable de entorno con ese nombre y que contenga el valor Smart::Comments; en ese caso cargará la librería a mano y los comentarios inteligentes harán su aparición durante el resto del proceso y para este paquete en concreto.

Una solución más elegante ...

Es la que proporciona un usuario de perlmonks llamado diotalevi en este hilo.

    1 use if $ENV{DEBUG}, 'Smart::Comments';

Es decir, hacer uso de un módulo Perl llamado if, del que no tenía idea de su existencia y que parece bastante prometedor (a pesar de lo farragoso de su código). Y aunque desarrollado como módulo, entra en la categoría de pragmas del lenguaje.

Podría quedar más o menos así si mezclamos las dos ideas:

    1 BEGIN {
    2     (my $package = __PACKAGE__) =~ s{::}{_}g;
    3 
    4     use if '$ENV{$package} =~ /Smart::Comments/', 'Smart::Comments';
    5 }

Me gusta más porque me permite:

  • Dejar libre la palabra DEBUG para la aplicación principal.
  • Especificar qué librerías exactamente quiero tener con comentarios inteligentes.
  • Pasar más información a una librería en concreto (advertir la expresión regular en la condición) y no limitarla sólo a esta característica.

Su síntaxis también cuenta

Los comentarios inteligentes son expresiones Perl y como tal pueden fallar estrepitosamente si están mal escritas. Conviene hacer una comprobación de síntaxis (perl -cw) con esta librería activa para descartar fallos en la ejecución; no hacerlo complica bastante la tarea de depuración porque ya son dos frentes abiertos: tú código y los comentarios.