Práctica: Un Módulo OOP Simple

Escriba un programa que haga uso del módulo Biblio::Doc presentado en la sección 6.1. Haga uso de h2xs.

Modifique la clase Biblio::Doc para que la subrutina _incr_count sea realmente privada, esto es, su ámbito de visibilidad quede limitado al fichero que describe la clase. ¿Qué cambios son necesarios?

Casiano Rodríguez León
2010-03-03
nits; 50 } 51 }

Las claves en %args no van precedidas de guión bajo (se supone que la llamada desde el programa cliente usará los nombres de los atributos sin guión bajo). Si la clave no figura en %args se inicializa al valor por defecto.

Las Claves Correctas

Observe que el uso de $self->_standard_keys en el bucle de la línea 44 nos protege contra errores de inicializaciones con claves inexistentes en el objeto, posiblemente como consecuencia de un error en la llamada desde el cliente (quizá debidos a un error tipográfico).

Habría además que comprobar que todas las claves en %args están en el conjunto de claves legales.

El Constructor

En la línea 57 se bendice el objeto aún sin inicializar.

53	sub new {
54	  my $class = shift;
55	  my $self = {};
56	
57	  bless $self, ref($class) || $class;
58	
59	  $self->_incr_count();
60	  $self->_init(@_);
61	
62	  return $self;
63	}
Cuando el constructor es llamado mediante Biblio::Doc->new() la variable $class contendrá la cadena 'Biblio::Doc' por lo que ref($class) devuelve undef y $self será bendecido en 'Biblio::Doc'.

Formas de LLamada de un Constructor

La línea 57 esta escrita pensando que el constructor pueda ser llamado de la forma $x->new donde $x es un objeto de la clase Biblio::Doc. Como sabemos, en tal caso ref($x) contendrá la cadena 'Biblio::Doc'. Asi pues, $self será, también en este caso, bendecido en 'Biblio::Doc'.

Desacomplando la Inicialización de la Construcción

Observe como hemos desacoplado la inicialización de la creación y bendición de la estructura. Es posible que durante el periodo de desarrollo del módulo la estructura del hash cambie, introduciendo nuevos atributos o suprimiendo algunos existentes. Con el desacoplado conseguimos que estos cambios no afecten a new (aunque si a _init).

El Destructor

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

65	sub DESTROY {
66	  my $self = shift;
67	
68	  $self->_decr_count();
69	}

Métodos de Acceso a los Atributos

También hemos extendido la subrutina AUTOLOAD para que compruebe (líneas 74 y 82) que el método de acceso requerido está permitido.

71	sub AUTOLOAD {
72	  no strict "refs";
73	  my $self = shift;
74	  if (($AUTOLOAD =~ /\w+::\w+::get(_.*)/) && ($self->_accesible($1,'read'))) {
75	    my $n = $1;
76	    die "Error in $AUTOLOAD: Illegal attribute\n" unless exists $self->{$n};
77	
78	    # Declarar el metodo get_*****
79	    *{$AUTOLOAD} = sub { return $_[0]->{$n}; };
80	
81	    return $self->{$n};
82	  } elsif (($AUTOLOAD =~ /\w+::\w+::set(_.*)/) && ($self->_accesible($1,'write'))) {
83	    my $n = $1;
84	    die "Error in $AUTOLOAD: Illegal attribute\n" unless exists $self->{$n};
85	    $self->{$n} = shift;
86	
87	    # Declarar el metodo set_*****
88	    *{$AUTOLOAD} = sub { $_[0]->{$n} = $_[1]; };
89	  } else {
90	    die "Error: Function $AUTOLOAD not found\n";
91	  }



Subsecciones
Casiano Rodríguez León
2011-02-09