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.
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.
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 }
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:
$VERSION
Se usa asi:
use NuestroModulo '1.5' # Si $VERSION < 1.5 error
@EXPORT
Contiene la lista de funciones y variables que serán exportadas por defecto al espacio de nombres del cliente.
EXPORT_OK
Este vector contiene los símbolos que serán cargados únicamente si se pregunta específicamente por ellos. Si los vectores se cargan asi:
@EXPORT = qw(&F1 &F2 @List); @EXPORT_OK = qw(Op_Func %table);Y el usuario carga el módulo como sigue:
use NuestroModulo qw(Op_Func %Table F1);Entonces importamos las funciones
Op_func
y F1
y el hash %Table
pero no la función F2
y el vector @List
.
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.
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:
use Trivial::Tutu;
Esto nos exportaría uno dos
.
use Trivial::Tutu qw(uno dos)
Lo mismo.
use Trivial::Tutu qw(tres cinco)
Ahora obtenemos tres cinco
. No se importan uno dos
.
use Trivial::Tutu();
No se importa ningún símbolo.
use Trivial::Tutu(siete);
Es un error. Todo símbolo importado debe estar
bien en la lista @EXPORT
bien en la lista
@EXPORT_OK
.
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
).
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)
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.
Recuerde consultar la documentación de
Exporter
con perldoc Exporter
.