Destructores

Perl elimina automáticamente la memoria de un objeto cuando es claro que ya no va a ser utilizado. Un método con el nombre especial DESTROY se dispara cuando la memoria asociada con un objeto debe ser eliminada (normalmente por que salimos de su ámbito de existencia).

Observe el siguiente código:

$ cat destructors.pl
 1	#!/usr/bin/perl -w
 2	
 3	{
 4	my $a = 4;
 5	
 6	print $a,"\n";
 7	}
 8	$a = "objeto apuntado por \$b";
 9	$b = \$a;
10	bless $b;
11	
12	sub DESTROY {
13	  my $self = shift;
14	  printf("\n****\n$$self eliminado a las %s\n", scalar localtime);
15	}
Al ejecutarlo obtenemos la salida:

$ ./destructors.pl
4

****
objeto apuntado por $b eliminado a las Thu May 20 14:31:42 2004
La eliminación de la variable léxica $a en la línea 4 no conlleva la llamada a DESTROY. sin embargo si que la implica la eliminación del objeto referenciado por $b.

Realmente la programación explícita de un destructor es requerida en muy pocas ocasiones: cuando el objeto es una interfaz con el mundo exterior o cuando contiene estructuras de datos circulares. En esos casos podemos aprovecharlo para suprimir ficheros temporales, romper enlaces circulares, desconectarnos de un ''socket'' o ''matar'' ciertos subprocesos que hayamos generado. No es necesario liberar explícitamente memoria, simplemente debemos colocar ahi cualquier código de liberación de recursos y limpieza que sea razonable para la finalización del objeto en cuestión.

Mientras que un constructor tiene un nombre arbitrario, un destructor no. Esto es debido a que los destructores se llaman automáticamente por el sistema de recolección de basura (''garbage collection'') de Perl. En general, Perl utiliza el convenio de que, aquellas funciones que son llamadas automáticamente se escriben en mayúsculas. Otras funciones que son llamadas implícitamente son BEGIN, END y AUTOLOAD.

Una sutileza con los destructores aparece cuando se ha escrito una rutina AUTOLOAD en el paquete. Como se sabe, AUTOLOAD es ejecutada siempre que no este definido el método invocado. La clave aquí es que ''siempre'' incluye también las llamadas a los destructores.

Obsérve la queja producida al ejecutar el programa cliente descrito en la sección 6.3:

 
Has llamado a Biblio::Doc::DESTROY() y no existe!

Una solución simple para esta situación consiste en definir un método DESTROY vacío.

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