Volcado automático de una variable

Como ejemplo, supongamos que queremos depurar una variable de paquete. Podemos modificar la interfaz de acceso a dicha variable para que, cada vez que activemos el ''modo depuración'' se imprima el valor de dicha variable. La utilización se muestra con el programa de uso:
 1	#!/usr/bin/perl -w -I.
 2	use Inspector;
 3	
 4	  $x = 10;
 5	  Inspector->scalar($x, 1);
 6	  $x = 20;
 7	  Inspector->debug($x,0);
 8	  $x = 30;
 9	  $x += 5;
10	  Inspector->debug($x,1);
11	  $x += 10;
al ejecutarse da como resultado:
~/perl/src> use_Inspector.pl
val=20 use_Inspector.pl:6:main
val=45 use_Inspector.pl:11:main
La idea es que una llamada a Inspector->scalar($x, 1) ata la variable $x (que será su argumento $_[1]) a la clase Inspector (argumento $_[0]). El tercer argumento lógico, indica si queremos activar o desactivar la depuración de la variable. Una vez atada, podemos usar el método Inspector->debug para controlar el rastreo de la variable.
package Inspector;

sub TIESCALAR {
  my ($class, $val, $debug) = @_;
  bless { val => $val, debug => $debug }, $class;
}

sub FETCH {
  my $impl = shift;
  return $impl->{val};
}

sub STORE {
  my ($implementation, $newval) = @_;
  $implementation->{val} = $newval;
  if ($implementation->{debug}) {
    my ($cur_pkg, $cur_file, $cur_line) = caller;
    print STDERR "val=$implementation->{val} $cur_file:$cur_line:$cur_pkg\n";
  }
}

sub scalar {
  my ($class, $var, $debug) = @_;
  tie $_[1], $class, $_[1], $debug; 
}

sub debug {
  my $impl = tied($_[1]);
  my $deb = $_[2];

  $impl->{debug} = $deb;
}

1;
La llamada a Inspector->scalar($x, 1) conlleva a través de tie una llamada a la función TIESCALAR que es la que construye el ''hash'' anónimo. La entrada val guarda el valor de la variable. La entrada debug indica si los valores de la variable deben o no ser volcados a STDERR cuando se cambia su valor. Por último TIESCALAR bendice el ''hash'' y devuelve su referencia como el objeto que reimplementa a la variable original.

Toda modificación de la variable se hace a través de STORE, la cuál después de cumplir con la reglamentaria asignación imprime los valores por STDERR si es el caso.

Puesto que no hemos provisto de métodos de acceso a la implementación interna de la variable hemos tenido que usar la función tied . Esta función recibe una variable como argumento y, si esta ''atada'' a un objeto devuelve una referencia al objeto. En otro caso devuelve undef. Asi pues, debug llama primero a tied y después establece el valor de la entrada debug del ''hash''.

Casiano Rodríguez León
Licencia de Creative Commons
Principios de Programación Imperativa, Funcional y Orientada a Objetos Una Introducción en Perl/Una Introducción a Perl
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=43.
2012-06-19