Uso del Módulo de Exportación

Es un poco incómodo tener que prefijar los objetos del módulo con el nombre completo. Esto se puede obviar usando el módulo Exporter. De hecho para que un package pueda ser considerado un módulo no basta con que esté en un fichero separado con sufijo .pm, debe tener (o heredar) un método de exportación y definir una lista de símbolos (que puede ser vacía) que son automáticamente exportados y/o una lista de símbolos (que puede ser vacía) que son exportados a petición.

Heredando de Exporter

El módulo Exporter provee diferentes mecanismos para realizar la interfaz pública del módulo que estamos desarrollando.

En el ejemplo que sigue, la inicialización del vector especial @ISA en la línea 5 hace que (junto que el use Exporter de la línea 3) el módulo Modexample::HopsExport ''herede'' de Exporter los métodos que nos hacen falta como import.

lhp@nereida:~/projects/perl/src$ cat -n Modexample/HopsExport.pm
 1  package Modexample::HopsExport;
 2  use strict;
 3  use Exporter;
 4
 5  our @ISA = ('Exporter');
 6  our @EXPORT = qw(&hop_along);
 7
 8  sub hop_along {
 9    my ($from, $to, $step) = @_;
10    my $next = $from-$step;  # incializar contador
11    my $closure_ref = sub {
12      $next += $step;
13      $next = $from-$step, return if $next > $to;
14      $_[0] =$next;
15      return 1;
16    };
17    return $closure_ref;
18  }
19
20  1;
Aún cuando no hemos visto objetos, puede dar una ojeada a la sección 6.5 que trata sobre la herencia. La herencia indica que los métodos definidos y exportados por los paquetes en el array @ISA estan disponibles en el módulo cliente.

EXPORT y EXPORT_OK

El método import que proporciona Exporter examina la lista de cadenas en @EXPORT para determinar que funciones y variables se exportan por defecto.

Si tenemos variables o rutinas que sólo deben ser exportadas bajo demanda del cliente (como foo en use Tutu qw(foo)) debemos escribir sus nombres en la lista @EXPORT_OK.

La línea de asignación a la variable @EXPORT hace que se cree un alias para la función hop_along en el programa cliente. De este modo no es necesario llamar a la función por su nombre completo Modexample::HopsExport::hop_along sino simplemente hop_along.

lhp@nereida:~/Lperl/src$ cat -n usehopsexport.pl
 1  #!/usr/bin/perl -w -I.
 2  use strict;
 3  use Modexample::HopsExport;
 4
 5  my ($r, $c);
 6  my $row = hop_along 1, 5, 1;
 7  my $col = hop_along 1, 5, 1;
 8  while ($row->($r)) {
 9    while ($col->($c)) {
10      print("($r, $c)\t");
11    }
12    print "\n";
13  }

Reglas de Exportación

El módulo Exporter permite definir de manera precisa la interfaz externa de nuestro módulo. Para ello deberemos escribir el siguiente código en NuestroModulo.pm

package NuestroModulo;
use strict;
use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);

use Exporter;

$VERSION = '1.00';
@ISA = qw(Exporter);

@EXPORT = qw(...); # Símbolos a exportar 
@EXPORT_OK = qw(...); # Símbolos a exportar a petición
%EXPORT_TAGS = (
  TAG1 => [...],
  TAG2 => [...],
  ...
);

######################
Nuestro código va aqui
######################

1;
En los ficheros desde los que queremos usar nuestro módulo deberemos escribir una de estas líneas:
use NuestroModulo;         # Importar los símbolos por defecto
use NuestroModulo qw(...); # Importar los símbolos listados
use NuestroModulo ();      # No importar símbolos
use NuestroModulo qw(:TAG1)# Importar el conjunto del tag

Cuando alguien escribe use NuestroModulo, ello implica un require "NuestroModulo.pm" seguido de una llamada a NuestroModulo->import() durante la compilación.

El método import, que es heredado del módulo EXPORTER usa un conjunto de variables en el paquete que gobiernan la conducta de exportación del módulo. Estas variables son:

Puesto que las variables @EXPORT, @EXPORT_OK y %EXPORT_TAGS son del paquete cuyo nombre casa con el del fichero5.1, es necesario declararlas con ours o bien utilizar el pragma use vars para satisfacer el uso de use strict sin que se produzcan mensajes de error.

Usando use

Supongamos el módulo:

package Trivial::Tutu;
our @EXPORT = qw(uno dos);
our @EXPORT_OK = qw(tres cuatro cinco);
use Exporter;
our @ISA = qw(Exporter);

Los siguientes ejemplos ilustran el modo de uso de la exportación:

Visbilidad de las Funciones

Observe que un programa cliente siempre puede acceder a las variables de paquete del módulo y a sus funciones, incluso si no figuran como símbolos exportables, sin mas que escribir su nombre completo (por ejemplo Trivial::Tutu::siete).

La Etiqueta :DEFAULT

Si lo que se quiere es obtener todo lo que hay en @EXPORT además de los ''extras'' se deberá usar la etiqueta especial :DEFAULT. Por ejemplo:

use NuestroModulo qw(:DEFAULT %Table)

Uso de etiquetas: el hash EXPORT_TAGS

El ''hash'' %EXPORT_TAGS es usado por módulos que proveen un gran número de funciones, como es el caso de CGI o POSIX para crear grupos de alto nivel de símbolos relacionados. Por ejemplo:

%EXPORT_TAGS = (
  Functions => [ qw(F1 F2 Op_Func) ],
  Variables => [ qw(@List %Table)  ],
);

Un símbolo de la lista de importación precedido de dos puntos indica una etiqueta:

use NuestroModulo qw(:Functions %Table);

Como se ha dicho, el módulo CGI.pm funciona con esta filosofía. Véase el siguiente ejemplo que usa CGI en el que se carga el grupo :standard:

$ cat -n cgitaste.pl
 1  #!/usr/bin/perl -w
 2  use CGI qw(:standard);
 3
 4  print header;
 5  print start_html('Un ejemplo Sencillo'),
 6      h1('Un ejemplo Sencillo'),
 7      start_form,
 8      "¿Tu nombre? ",textfield('nombre'),
 9      p,
10      "¿Matriculado en?",
11      checkbox_group(-name=>'estudios',
12                     -values=>['Sistemas','Gestión','Superior'],
13                     -defaults=>['sistemas']),
14      p,
15      "¿Lenguaje favorito? ",
16      popup_menu(-name=>'len',
17                 -values=>['C','C++','Pascal','Java','Lisp','Prolog','Python','Perl']),
18      p,
19      submit(-name=>"Enviar"),
20      end_form,
21      hr;
22
23  if (param()) {
24      print h1('Tus datos:'),
25          p,
26          "Nombre: ",em(param('nombre')),
27          p,
28          "Estudios: ",em(join(", ",param('estudios'))),
29          p,
30          "Lenguaje favorito: ",em(param('len')),
31          hr;
32  }
33  print end_html;
Puede ejecutar este ejemplo en http://nereida.deioc.ull.es/lhp-cgi/cgitaste.pl.

Referencias

Recuerde consultar la documentación de Exporter con perldoc Exporter.



Subsecciones
Casiano Rodríguez León
2009-10-04