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.