next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Ejercicio: Mutators y Autocarga Sup: Programación Orientada a Objetos Ant: Práctica: Generación Automática de Err: Si hallas una errata ...


Generación Automática de Accesors/Mutators

La solución del ejercicio 7.1.4 es ineficiente. es posible mejorar la eficiencia, haciendo que cada vez que se busca una función y no se encuentra, AUTOLOAD dinámicamente se instale una entrada con la función en la tabla de símbolos, de manera que la siguiente llamada encuentre el método. Para ello usaremos un ``typeglob'' y una subrutina anónima. Sigue el código del módulo:
 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!



Subsecciones
next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Ejercicio: Mutators y Autocarga Sup: Programación Orientada a Objetos Ant: Práctica: Generación Automática de Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21