$self->B::method();es que si se cambia el nombre de la clase o se modifica la jerarquía de clases habrá que reescribir esa parte del código. Es posible en ocasiones evitar dicha codificación con el nombre explícito de la clase madre utilizando un identificador de paquete SUPER el cual nos permite referirnos a las clases madres de la clase actual:
$self->SUPER::method();Mas que un sinónimo de
B
, lo que hace SUPER
es indicarle a Perl que la búsqueda
del método debe realizarse desde el vector @ISA
de la clase en la que el método
está siendo llamado.
Veamos un ejemplo:
~/perl/src> cat A.pl #!/usr/bin/perl -w -I. use A; $x = A->new(); print ref($x),"\n"; $x->x();
Los módulos implicados son:
$ cat ./A.pm package A; use B; use C; @ISA = ("B", "C"); sub x { $self = shift; $self->SUPER::t(); } sub t { print "t de A\n"; } 1; |
$ cat B.pm package B; sub new { my $class = shift; bless {}, $class; } 1; |
$ cat C.pm package C; sub new { my $class = shift; bless {}, $class; } sub t { print "C\n"; } 1; |
La ejecución da como resultado:
/perl/src> A.pl A CLa llamada
$x->x()
produce una llamada a $self->SUPER::t()
. Dado
que la búsqueda comienza en las clases especificadas en el vector @ISA
de la clase A
y que la clase B
no tiene ningún método denominado t()
, se encuentra
el método t()
de la clase C
.
El prefijo SUPER:: se refiere a la clase que hace la llamada, como muestra el siguiente ejemplo:
main::(-e:1): 0 DB<1> @A::ISA = qw{B}; @B::ISA = qw{C}; @C::ISA =() DB<2> sub C::tutu { 8 } DB<3> $x = bless {}, 'A' DB<4> x $x->SUPER::tutu Can't locate object method "tutu" via package "main" at \ (eval 8)[/usr/share/perl/5.8/perl5db.pl:628] line 2. DB<5> x $x->tutu 0 8 DB<6> package A; $x = bless {}, 'A'; print $x->SUPER::tutu,"\n" 8
Casiano Rodríguez León