1 package Biblio::Doc1; 2 $VERSION = 1.00; 3 use strict; 4 use vars qw/$AUTOLOAD/;La declaración
use vars
es similar a ours
.
6 { 7 my $_count = 0; 8 sub get_count { $_count } 9 sub incr_count { $_count++ } 10 } 11 12 sub new { 13 my $class = shift; 14 my ($identifier, $author, $publisher, $title, $url) = @_; 15 incr_count(); 16 my $document = { 17 _identifier => $identifier, 18 _author => $author, 19 _publisher => $publisher, 20 _title => $title, 21 _url => $url, 22 }; 23 24 bless $document, $class; 25 } 26 27 sub AUTOLOAD { 28 no strict "refs"; 29 30 my $self = shift; 31 if ($AUTOLOAD =~ /\w+::\w+::get(_.*)/) { 32 my $n = $1; 33 return unless exists $self->{$n}; 34 35 # Declarar el metodo get_***** 36 *{$AUTOLOAD} = sub { return "(nuevo get) ".$_[0]->{$n}; }; 37 38 return "(autoload) ".$self->{$n}; 39 } elsif ($AUTOLOAD =~ /\w+::\w+::set(_.*)/) { 40 my $n = $1; 41 return unless exists $self->{$n}; 42 $self->{$n} = "(autoload) ".shift; 43 44 # Declarar el metodo set_***** 45 *{$AUTOLOAD} = sub { $_[0]->{$n} = "(nuevo set) ".$_[1]; }; 46 } else { 47 @_ = map { "\"".$_."\""; } @_; # Comillas a los argumentos... 48 print "Has llamado a $AUTOLOAD(",join(", ",@_),") y no existe!\n"; 49 } 50 } 51 52 1;En la línea 31 obtenemos el nombre del atributo y lo guardamos (línea 32) en
$n
. En la línea 33 comprobamos que tal atributo existe.
La subrutina anónima que crea AUTOLOAD
en la línea 36 es una clausura con respecto a $n
:
el valor se recuerda, incluso después que se haya
salido del ámbito.
Obsérvese la asignación de la línea 36:
*{$AUTOLOAD} = sub { return "(nuevo get) ".$_[0]->{$n}; };Esto hace que se instale una entrada con el nombre del método deseado en la tabla de símbolos. El
use strict
hace que el compilador se queje, ya que el
lado derecho es una referencia a subrutina y el lado izquierdo un ``typeglob'':
~/perl/src> use_Biblio_Doc.1.pl Can't use string ("get_author") as a symbol ref while "strict refs" in use at Biblio/Doc1.pm line 36. Has llamado a Biblio::Doc1::DESTROY() y no existe!Podemos hacer que la queja desaparezca, escribiendo al comienzo de
AUTOLOAD
la
directiva:
no strict "refs";hace que
strict
deje de controlar el uso de referenciado
simbólico en el ámbito en el que se ubique.
Sigue un ejemplo de programa cliente:
#!/usr/bin/perl -w -I. use Biblio::Doc1; $obj = Biblio::Doc1->new(1, "Asimov", "Bruguera", "Los propios dioses", "unknown"); print ("El nombre del autor es: ", $obj->get_author(), "\n"); print ("La URL es: ", $obj->get_url(), "\n"); $obj->set_author("El buen doctor"); print ("El nuevo nombre del autor es: ", $obj->get_author(), "\n"); $obj->set_author("Isaac Asimov"); print ("El nombre del autor definitivo es: ", $obj->get_author(), "\n");La ejecución del programa anterior produce la salida:
~/perl/src> use_Biblio_Doc.1.pl El nombre del autor es: (autoload) Asimov La URL es: (autoload) unknown El nuevo nombre del autor es: (nuevo get) (autoload) El buen doctor El nombre del autor definitivo es: (nuevo get) (nuevo set) Isaac Asimov Has llamado a Biblio::Doc1::DESTROY() y no existe!