_init de un antepasado
se repita dos veces (una por cada camino hasta el antepasado)
para el mismo objeto.
Una solución es rastrear que inicializadores han sido visitados
y evitar las subsiguientes visitas. Por ejemplo, si la clase
C del ejemplo anterior es un candidato a inicializaciones repetidas (esto es,
si puede ser la cúspide de un diamante), la podemos proteger usando el
condicional que aparece en la línea 6
(Véase [18] para mas detalles):
1 package C;
2 @C::ISA = qw( _I B A);
3
4 sub _init {
5 my ($self, %args) = @_;
6 return if $self->{_init}{__PACKAGE__}++;
7 $self->A::_init(%args);
8 $self->B::_init(%args);
9 $self->{_c1} = $args{c1};
10 }
La macro __PACKAGE__ es igual al nombre del paquete actual
(en este caso el paquete C). El uso de __PACKAGE__
puede ser de ayuda si por alguna razón decidimos
copiar el código de _init en otro paquete: No tenemos
que sustituir las apariciones de C por el nombre del
nuevo paquete.
Una estrategia parecida puede aplicarse para evitar la llamada reiterada a destructores cuando se producen estructuras jerarquicas en diamante.
Casiano Rodríguez León
