perl module relative-path use

¿Cómo ''uso'' un módulo Perl en un directorio que no está en @INC?



module relative-path (6)

Tengo un módulo en el directorio padre de mi script y me gustaría ''usarlo''.

Si lo hago

use ''../Foo.pm'';

Obtengo errores de sintaxis

Intenté hacer:

push @INC, ''..''; use EPMS;

y ... aparentemente no aparece en @INC

¡Me estoy volviendo loco! ¿Qué pasa aquí?


''use lib'' es la respuesta, como @ephemient se mencionó anteriormente. Otra opción es usar require / import en lugar de usar. Significa que el módulo no se cargará en tiempo de compilación, sino en tiempo de ejecución.

Eso le permitirá modificar @INC como lo intentó allí, o podría pasar requerir una ruta al archivo en lugar del nombre del módulo. De ''perldoc -f require'':

Si EXPR es una palabra clave, el requerimiento asume una extensión ".pm" y reemplaza "::" con "/" en el nombre del archivo por usted, para que sea más fácil cargar módulos estándar. Esta forma de carga de módulos no corre el riesgo de alterar su espacio de nombres.


Hay varias formas de modificar @INC .

  • establecer PERL5LIB, como se documenta en perlrun

  • use el interruptor -I en la línea de comando, también documentada en perlrun . También puede aplicar esto automáticamente con PERL5OPT, pero simplemente use PERL5LIB si va a hacer eso.

  • use lib dentro de su programa, aunque esto es frágil ya que otra persona en una máquina diferente podría tenerlo en un directorio diferente.

  • Modifique manualmente @INC , asegurándose de hacerlo en tiempo de compilación si desea utilizar un módulo. Eso es demasiado trabajo sin embargo.


Personalmente, prefiero mantener mis módulos (los que escribo para mí o para los sistemas que puedo controlar) en un directorio determinado, y también para colocarlos en un subdirectorio. Como en:

/www/modules/MyMods/Foo.pm /www/modules/MyMods/Bar.pm

Y luego donde los uso:

use lib qw(/www/modules); use MyMods::Foo; use MyMods::Bar;

Como un aparte ... cuando se trata de empujar, prefiero la coma de flecha de grasa:

push @array => $pushee;

Pero eso es solo una cuestión de preferencia.


Según lo informado por "perldoc -f use":

Es exactamente equivalente a
BEGIN { require Module; import Module LIST; }
excepto que el Módulo debe ser una palabra sencilla.

Dicho de otra manera, "usar" es equivalente a:

  • corriendo en tiempo de compilación,
  • convirtiendo el nombre del paquete en un nombre de archivo,
  • require ese nombre de archivo, y
  • import ese paquete.

Entonces, en lugar de llamar a usar, puede llamar a require e importar dentro de un bloque BEGIN:

BEGIN { require ''../EPMS.pm''; EPMS->import(); }

Y, por supuesto, si su módulo no exporta ningún símbolo u otra inicialización cuando llama a importar, puede dejar esa línea:

BEGIN { require ''../EPMS.pm''; }


push procesar el push antes de use , y el use se procesa temprano. Por lo tanto, necesitará un BEGIN { push @INC, ".."; } BEGIN { push @INC, ".."; } tener una oportunidad, creo.


use lleva a cabo en tiempo de compilación, por lo que esto funcionaría:

BEGIN {push @INC, ''..''} use EPMS;

Pero la mejor solución es use lib , que es una forma más agradable de escribir lo anterior:

use lib ''..''; use EPMS;

Sin embargo, en caso de que esté ejecutando desde un directorio diferente, se recomienda el uso de FindBin :

use FindBin; # locate this script use lib "$FindBin::RealBin/.."; # use the parent directory use EPMS;