La notación SUPER

La delegación de parte de las fase de inicialización a las clases antepasadas es común cuando se usa herencia. Es conveniente evitar la codificación ''dura'' de clases antepasadas en el código como se hizo en la sección 6.6.4. El problema con una llamada de la forma
$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
C
La 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
Licencia de Creative Commons
Principios de Programación Imperativa, Funcional y Orientada a Objetos Una Introducción en Perl/Una Introducción a Perl
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=43.
2012-06-19