Paquetes y Ficheros

¿Un Paquete por Fichero?

En principio no hay relación directa entre paquetes y ficheros: un mismo paquete puede existir en diversos ficheros y diversos paquetes pueden ser declarados en un único fichero.

Sufijos

Como un paquete generalmente se hace para ser reutilizado muchas veces, se guarda en un archivo libreria de extension .pl (por ejemplo cgilib.pl) o en un archivo módulo con el sufijo .pm.

Cargando una Librería con require

Los programas que quieren usar las subrutinas en la librería pueden invocar el fichero con require

lhp@nereida:/tmp$ perl -wde 0
main::(-e:1):   0
  DB<1> require GRID::Machine    # Cargada

  DB<2> require "GRID::Machine"  # Error
Can't locate GRID::Machine in @INC (@INC contains: 
/etc/perl
/usr/local/lib/perl/5.8.8
/usr/local/share/perl/5.8.8
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.8
/usr/share/perl/5.8
/usr/local/lib/site_perl
/usr/local/lib/perl/5.8.7
/usr/local/share/perl/5.8.7
/usr/local/lib/perl/5.8.4
/usr/local/share/perl/5.8.4.)
at (eval 17)[/usr/share/perl/5.8/perl5db.pl:628] line 2.

  DB<3> require "GRID/Machine.pm" # Cargada

  DB<4> x %INC
0  're.pm'
1  '/usr/lib/perl/5.8/re.pm'
2  'attributes.pm'
3  '/usr/share/perl/5.8/attributes.pm'
..  ....................................................
42  'GRID/Machine.pm'
43  '/usr/local/share/perl/5.8.8/GRID/Machine.pm'
..  ....................................................
60  'GRID/Machine/MakeAccessors.pm'
61  '/usr/local/share/perl/5.8.8/GRID/Machine/MakeAccessors.pm'
62  'Module/Which.pm'
63  '/usr/local/share/perl/5.8.8/Module/Which.pm'
64  'GRID/Machine/Result.pm'
65  '/usr/local/share/perl/5.8.8/GRID/Machine/Result.pm'
..  ....................................................
110  'Term/ReadLine/Gnu.pm'
111  '/usr/lib/perl5/Term/ReadLine/Gnu.pm'

la función require lee el archivo si este no ha sido leido antes.

En el hash especial %INC están las librerías cargadas. Obsérvense las líneas 42 y 43.

El módulo Module::Util proporciona la función module_path que devuelve el camino relativo para un módulo. Así si se quiere saber donde está un módulo:

  DB<1> use GRID::Machine
  DB<2> use Module::Util qw( :all );
  DB<3> x $INC{module_path('GRID::Machine')}
0  '/soft/perl5lib/share/perl/5.8.8//GRID/Machine.pm'
o bien:
  DB<4> x module_is_loaded('GRID::Machine')
0  '/soft/perl5lib/share/perl/5.8.8//GRID/Machine.pm'

El archivo cargado no tiene que necesariamente estar asociado con un package. Su evaluación por require debe devolver verdadero. Por ello la última sentencia ejecutada deberá devolver una valor cierto. De aquí que un paquete normalmente termine con:

return 1;

Si se omiten las comillas y el sufijo, se asume una extensión .pm:

lhp@nereida:/tmp$ perl -wde 0
main::(-e:1):   0
  DB<1> require "CGI"    # Error
Directory /usr/local/share/perl/5.8.8/CGI not allowed in require at (eval 5)[/usr/share/perl/5.8/perl5db.pl:628] line 2.
  DB<2> require CGI      # OK
  DB<3> require "CGI.pm" # OK

''use'' Ocurre Durante la Compilación

Mientras que require carga el paquete en tiempo de ejecución, comprobando que no esta ya cargado, use carga los módulos en tiempo de compilación.

El siguiente código no funciona:

$paquete = "MiPaquete"; # se ejecuta en tiempo de ejecución
use $paquete; # se ejecuta en tiempo de compilación
Además use requiere que el sufijo del fichero sea .pm



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