Búsqueda de Librerías y Módulos

La Lista de Caminos de Módulos: @INC

Cuando se compila una sentencia use module se produce la búsqueda por el fichero conteniendo module.

El fichero conteniendo el módulo o librería debe colocarse en uno de varios directorios estándar en los que el compilador busca. Esa lista esta disponible en un programa Perl a través de la variable @INC. Así puedes ver el camino de búsqueda escribiendo:

$ perl -e 'print "@INC\n";'
/usr/local/lib/perl/5.6.1 /usr/local/share/perl/5.6.1 /usr/lib/perl5
/usr/share/perl5 /usr/lib/perl/5.6.1 /usr/share/perl/5.6.1
/usr/local/lib/site_perl .
si tienes mas de una versión de Perl, puede que difieran en sus caminos de búsqueda:
$ perl5.8.0 -e 'print "@INC\n";'
/usr/local/lib/perl5/5.8.0/i686-linux /usr/local/lib/perl5/5.8.0
/usr/local/lib/perl5/site_perl/5.8.0/i686-linux
/usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl .
Otra posibilidad es llamar a Perl con la opción -V (versión):
$ perl5.8.0 -V
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
...
Characteristics of this binary (from libperl):
  Compile-time options: USE_LARGE_FILES
  Built under linux
  Compiled at May 14 2003 16:02:03
  @INC:
    /usr/local/lib/perl5/5.8.0/i686-linux
    /usr/local/lib/perl5/5.8.0
    /usr/local/lib/perl5/site_perl/5.8.0/i686-linux
    /usr/local/lib/perl5/site_perl/5.8.0
    /usr/local/lib/perl5/site_perl
    .

El Significado de ::

El compilador sustituye cada :: por el separador de caminos. Asi la orden: use Text::ParseWords; se traduce por el fichero Text/ParseWords.pm. En cierta máquina el directorio exacto podría ser algo similar a /usr/lib/perl5/5.00503/Text/ParseWords.pm

La Evaluación de use Text::ParseWords

El compilador Perl abre el primer fichero en el camino de búsqueda que case con Text/ParseWords.pm y evalúa el texto en su interior. Si falla, la compilación termina con un mensaje de error. En otro caso, el compilador busca en el módulo por una rutina denominada import y si existe la ejecuta. Cuando esta termina la compilación continúa en el fichero original, justo después de la línea en la que aparece la sentencia use.

Añadir Directorios de Búsqueda

Si queremos especificar directorios adicionales de búsqueda podemos optar por una de estas opciones:

  1. Utilizar la opción -I de la línea de comandos. Por ejemplo:

    perl -I/home/casiano/perl/src/packages/ -I/usr/local/test/perl first.pl

  2. Definir la variable PERL5LIB como secuencia de caminos de acceso separados por el símbolo dos puntos (:)

  3. Modificar la variable @INC:
    unshift(@INC, '/home/casiano/perl/src/packages/');
    require 'mypackage.pl';
    

  4. Usar el módulo lib el cual añade los caminos especificados como argumentos en tiempo de compilación:
    #!/usr/local/bin/perl5.8.0 -w
    use lib qw(/home/lhp/perl/src /home/lhp/public_html/cgi-bin);
    print "@INC \n";
    
    Al ejecutar nos da:
    bash-2.05b$ ./use_lib.pl
    /home/lhp/perl/src /home/lhp/public_html/cgi-bin
    /usr/local/lib/perl5/5.8.0/i686-linux /usr/local/lib/perl5/5.8.0
    /usr/local/lib/perl5/site_perl/5.8.0/i686-linux
    /usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl .
    

Modificar @INC en Tiempo de Compilación

Si se quiere garantizar que el camino en cuestión esta disponible antes de que se ejecute ninguna sentencia se puede usar una de las opciones 1 2 o 4. También podemos hacerlo rodeando la opción 3 de un BEGIN:

BEGIN {
  unshift @INC, "home/lhp/perl/src";
}

Cuando Perl esta en la fase de compilación y encuentra un bloque con nombre BEGIN pasa a ejecutarlo y continúa con la compilación. Puede existir mas de un bloque BEGIN en un programa, en cuyo caso se van ejecutando durante la fase de compilacion según se van viendo.

Ejercicio 5.5.1   Explique la siguiente salida:
casiano@beowulf:~/src/perl$ perl -de 0
DB<1> require Data::Dumper

DB<2> require "Data::Dumper"
Can't locate Data::Dumper 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 .) at (eval
18)[/usr/share/perl/5.8/perl5db.pl:628] line 2.
Observe que el primer require no produce ninguna queja, el segundo si. Consulte perldoc -f require para entender este detalle.



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