_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