¿Cuáles son todas las formas de afectar dónde se buscan los módulos Perl? o ¿Cómo se construye el @INC de Perl ?
Como sabemos, Perl usa una @INC
matriz que contiene nombres de directorio para determinar dónde buscar los archivos del módulo Perl .
No parece haber una publicación de tipo de preguntas frecuentes "@INC" exhaustiva en StackOverflow, por lo que esta pregunta está pensada como una.
perl
perl-module
DVK
fuente
fuente
@INC
en tiempo de ejecución, no la construcción completa.Respuestas:
Veremos cómo se construyen los contenidos de esta matriz y cómo se pueden manipular para afectar el lugar donde el intérprete de Perl encontrará los archivos del módulo.
Defecto
@INC
El intérprete de Perl se compila con un
@INC
valor predeterminado específico . Para encontrar este valor, ejecute elenv -i perl -V
comando (env -i
ignora laPERL5LIB
variable de entorno - vea # 2) y en la salida verá algo como esto:Nota
.
al final; Este es el directorio actual (que no es necesariamente el mismo que el directorio del script). Falta en Perl 5.26+, y cuando Perl se ejecuta con-T
(comprobaciones de manchas habilitadas) .Para cambiar la ruta predeterminada al configurar la compilación binaria Perl, configure la opción de configuración
otherlibdirs
:Variable ambiental
PERL5LIB
(oPERLLIB
)Perl se antepone
@INC
con una lista de directorios (separados por dos puntos) contenidos enPERL5LIB
(si no se define,PERLLIB
se usa) la variable de entorno de su shell. Para ver el contenido de@INC
afterPERL5LIB
yPERLLIB
las variables de entorno han tenido efecto, ejecuteperl -V
.-I
opción de línea de comandosPerl se antepone
@INC
con una lista de directorios (separados por dos puntos) pasados como valor de la-I
opción de línea de comandos. Esto se puede hacer de tres maneras, como es habitual con las opciones de Perl:Pásalo en la línea de comando:
Pásalo a través de la primera línea (shebang) de tu script Perl:
Pásalo como parte de
PERL5OPT
(oPERLOPT
) variable de entorno (ver capítulo 19.02 en Programación Perl )Pásalo por el
lib
pragmaPerl se antepone
@INC
con una lista de directorios pasados a través deuse lib
.En un programa:
En la línea de comando:
También puede eliminar los directorios de
@INC
viano lib
.Puede manipular directamente
@INC
como una matriz Perl normal.Nota: Dado que
@INC
se usa durante la fase de compilación, esto debe hacerse dentro de unBEGIN {}
bloque, que precede a lause MyModule
declaración.Agregar directorios al principio a través de
unshift @INC, $dir
.Agregue directorios al final a través de
push @INC, $dir
.Haga cualquier otra cosa que pueda hacer con una matriz Perl.
Nota: Los directorios son no desplazada en
@INC
el orden indicado en esta respuesta, por ejemplo, por defecto@INC
es el último en la lista, precedido porPERL5LIB
, precedida por-I
, precedidos poruse lib
directo y@INC
la manipulación, los dos últimos mezclarse en cualquier orden en que están en código Perl.Referencias
@INC
?No parece haber una
@INC
publicación completa de tipo FAQ en Stack Overflow, por lo que esta pregunta está pensada como una.¿Cuándo usar cada enfoque?
Si los módulos en un directorio necesitan ser utilizados por muchos / todos los scripts en su sitio, especialmente ejecutados por múltiples usuarios, ese directorio debe incluirse en el
@INC
compilado predeterminado en el binario de Perl.Si los módulos en el directorio serán utilizados exclusivamente por un usuario específico para todos los scripts que ejecuta el usuario (o si recompilar Perl no es una opción para cambiar el valor predeterminado
@INC
en el caso de uso anterior), configure los usuariosPERL5LIB
, generalmente durante el inicio de sesión del usuario.Nota: Tenga en cuenta las dificultades habituales de las variables de entorno Unix, por ejemplo, en ciertos casos, ejecutar los scripts ya que un usuario en particular no garantiza ejecutarlos con la configuración del entorno de ese usuario, por ejemplo, a través de
su
.Si los módulos en el directorio necesitan usarse solo en circunstancias específicas (por ejemplo, cuando el script (s) se ejecuta en modo de desarrollo / depuración, puede configurarlo
PERL5LIB
manualmente o pasar la-I
opción a perl.Si los módulos necesitan ser utilizados solo para scripts específicos, por todos los usuarios que los usen, use
use lib
/no lib
pragmas en el programa mismo. También debe usarse cuando el directorio a buscar debe determinarse dinámicamente durante el tiempo de ejecución, por ejemplo, a partir de los parámetros de la línea de comandos o la ruta del script (consulte el módulo FindBin para obtener un caso de uso muy agradable).Si los directorios
@INC
necesitan ser manipulados de acuerdo con una lógica complicada, ya sea imposible o demasiado difícil de implementar mediante la combinación deuse lib
/no lib
pragmas, entonces use la@INC
manipulación directa dentro delBEGIN {}
bloque o dentro de una biblioteca de propósito especial designada para la@INC
manipulación, que debe ser utilizada por su script (s) antes de utilizar cualquier otro módulo.Un ejemplo de esto es cambiar automáticamente entre bibliotecas en los directorios prod / uat / dev, con la recolección de la biblioteca en cascada en prod si falta en dev y / o UAT (la última condición hace que la solución estándar "use lib + FindBin" sea bastante complicada). ilustración detallada de este escenario es en ¿Cómo puedo utilizar módulos Perl beta desde scripts de Perl beta? .
Un caso de uso adicional para la manipulación directa
@INC
es poder agregar referencias de subrutina o referencias de objeto (sí, Virginia,@INC
puede contener código Perl personalizado y no solo nombres de directorio, como se explica en ¿ Cuándo se llama una referencia de subrutina en @INC? ).fuente
Además de las ubicaciones enumeradas anteriormente, la versión OS X de Perl también tiene dos formas más:
El archivo /Library/Perl/x.xx/AppendToPath. Las rutas enumeradas en este archivo se agregan a @INC en tiempo de ejecución.
El archivo /Library/Perl/x.xx/PrependToPath. Las rutas enumeradas en este archivo se anteponen a @INC en tiempo de ejecución.
fuente
Como ya se dijo, @INC es una matriz y eres libre de agregar lo que quieras.
Mi script CGI REST se ve así:
La subrutina desaparecida es exportada por Rest.pm.
fuente