Wie wird Perl @INC aufgebaut? (Aka Was sind alle Möglichkeiten zu beeinflussen, wo Perl-Module gesucht werden?)
-
22-09-2019 - |
Frage
Was sind alle Möglichkeiten zu beeinflussen, wo Perl-Module gesucht werden? oder Wie wird Perl @INC konstruiert ?
Wie wir wissen, Perl verwendet @INC
Array Namen enthält Verzeichnis, in dem, um zu bestimmen, um die Suche nach Perl-Modul Dateien .
Es scheint nicht, eine umfassende „@INC“ FAQ-Typ Post auf Stackoverflow zu sein, so dass diese Frage als eine bestimmt ist.
Lösung
Wir werden sehen, wie der Inhalt dieses Arrays ist so konstruiert und manipuliert werden können beeinflussen, wo die Perl-Interpreter werden die Moduldateien finden.
-
Standard
@INC
Perl-Interpreter mit einem bestimmten
@INC
Standardwert zusammengestellt. Um diesen Wert zu ermitteln, führteenv -i perl -V
Befehl (env -i
ignoriert diePERL5LIB
Umgebungsvariable - siehe # 2) und in der Ausgabe werden Sie etwas wie diese:$ env -i perl -V ... @INC: /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/site_perl/5.18.0 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/5.18.0 .
Hinweis .
am Ende; Dies ist das aktuelle Verzeichnis (die nicht unbedingt das gleiche wie das Skript des Verzeichnisses ist). Es fehlt in Perl 5.26+, und wenn Perl läuft mit -T
(taint Kontrollen aktiviert) .
Um den Standardpfad zu ändern, wenn Perl binäre Kompilierung Konfiguration, setzen Sie die Konfigurationsoption otherlibdirs
:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
-
Umgebungsvariable
PERL5LIB
(oderPERLLIB
)Perl pre-pends mit einer Liste von Verzeichnissen
@INC
(Kolon-getrennt) inPERL5LIB
enthalten (wenn es nicht definiert ist,PERLLIB
verwendet wird) Umgebungsvariablen der Shell. Um den Inhalt von@INC
nachPERL5LIB
undPERLLIB
Umgebungsvariablen genommen hat Wirkung, Laufperl -V
.$ perl -V ... %ENV: PERL5LIB="/home/myuser/test" @INC: /home/myuser/test /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/site_perl/5.18.0 /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld /usr/lib/perl5/5.18.0 .
-
-I
BefehlszeilenoptionPerl pre-pends mit einer Liste von Verzeichnissen
@INC
(Kolon-getrennt) als Wert der-I
Befehlszeilenoption übergeben. Dies kann auf drei Arten erfolgen, wie üblich mit Perl Optionen:-
Direkt zur Befehlszeile:
perl -I /my/moduledir your_script.pl
-
Direkt über die erste Leitung (shebang) Ihren Perl-Skript:
#!/usr/local/bin/perl -w -I /my/moduledir
-
Übergeben Sie es als Teil
PERL5OPT
(oderPERLOPT
) Umgebungsvariablen (siehe Kapitel 19.02 in Programming Perl )
-
-
Direkt über den
lib
PragmaPerl pre-pends
@INC
mit einer Liste von Verzeichnissen, um es überuse lib
übergeben.In einem Programm:
use lib ("/dir1", "/dir2");
Auf der Kommandozeile:
perl -Mlib=/dir1,/dir2
Sie können auch entfernen Sie die Verzeichnisse von
@INC
überno lib
. -
Sie können direkt
@INC
als regulären Perl-Array manipulieren.. Hinweis: Da
@INC
bei der Erstellung Phase verwendet wird, dies erfolgt innerhalb einesBEGIN {}
Block sein muss, die dieuse MyModule
Anweisung voraus-
Fügen Sie Verzeichnisse zu Beginn über
unshift @INC, $dir
. -
Fügen Sie Verzeichnisse Ende über
push @INC, $dir
. -
Do alles, was Sie mit einem Perl-Array tun können.
-
Hinweis: Die Verzeichnisse sind unshifted auf @INC
in der Reihenfolge, in dieser Antwort enthalten sind, beispielsweise Standard @INC
ist zuletzt in der Liste, die von PERL5LIB
voraus, von -I
voraus, mit vorangestellten use lib
und direkter @INC
Manipulation, wobei die beiden letzteren gemischt in je nachdem, was sie bestellt sind in Perl-Code.
Referenzen:
- Perldoc perlmod
- Perldoc lib
- Perl Module Mechanik - ein großer Führer mit praktischen Anleitungen
- Wie kann ich 'verwendet' ein Perl-Modul in einem Verzeichnis nicht in
@INC
? - Programmierung Perl - Kapitel 31 Teil 13, ch 7.2.41
- Wie funktioniert ein Perl-Programm wissen, wo die Datei Perl finden Modul enthält, verwendet es?
Es scheint nicht ein umfassender @INC
FAQ-Typ Beitrag auf Stack-Überlauf zu sein, so dass diese Frage als eine bestimmt ist.
Wenn jeden Ansatz benutzen?
-
Wenn die Module in einem Verzeichnis Notwendigkeit von vielen genutzt werden / alle Skripte auf Ihrer Website, vor allem durch mehrere Benutzer ausführen, sollte das Verzeichnis in dem Standard
@INC
in den Perl-Binary kompiliert aufgenommen werden. -
Wenn die Module in das Verzeichnis für alle Skripte, dass Benutzer läuft (oder wenn neu zu kompilieren Perl ist keine Option zu ändern Standard
@INC
in früheren Anwendungsfall) ausschließlich von einem bestimmten Benutzer verwendet werden, stellen die VerbraucherPERL5LIB
, in der Regel während der Benutzeranmeldung.Hinweis: Bitte beachten Sie die üblichen variablen Fallen Unix-Umgebung - zum Beispiel in bestimmten Fällen die Skripte als ein bestimmten Benutzer ausgeführt ist keine Garantie läuft sie mit dieser Umgebung des Benutzers einrichten, zum Beispiel
su
über. -
Wenn die Module in dem Verzeichnis Notwendigkeit, nur unter besonderen Umständen verwendet werden (zB wenn das Skript (n) in der Entwicklung / Debug-Modus ausgeführt wird, können Sie entweder Satz
PERL5LIB
manuell oder die-I
Option passieren zu perl . -
Wenn die Module müssen nur für bestimmte Skripte verwendet werden, von alle Benutzer mit ihnen Gebrauch
use lib
/no lib
Pragmas im Programm selbst. Es sollte auch verwendet werden, wenn das Verzeichnis Bedürfnisse durchsucht wird dynamisch zur Laufzeit bestimmt werden - z.B. aus dem Weg des Skript-Befehlszeilenparametern oder Skript (siehe FindBin Modul für sehr schön Anwendungsfall). -
Wenn die Verzeichnisse in
@INC
Bedürfnis nach einigen komplizierten Logik manipuliert werden, entweder unmöglich zu unhandlich durch Kombination vonuse lib
/no lib
Pragmas zu implementieren, verwenden Sie dann direkt@INC
Manipulation innerhalbBEGIN {}
Block oder in einer Zweck Bibliothek bezeichnet für@INC
Manipulation, die von Ihrem Skript (n) verwendet werden muss, bevor andere Module verwendet werden.Ein Beispiel hierfür schaltet automatisch zwischen Bibliotheken in prod / uat / dev Verzeichnissen, mit Wasserfall Bibliothek Abholung in prod, wenn es von dev fehlt und / oder UAT (die letzte Bedingung macht den Standard „use lib + FindBin“ Lösung ziemlich kompliziert. Eine detaillierte Darstellung dieses Szenarios ist in Wie verwende ich beta-Perl-Module von beta Perl-Skripte? .
-
Ein weiterer Anwendungsfall für
@INC
direkt Manipulation in der Lage sein Unterprogramm Referenzen oder Objektreferenzen hinzufügen (ja, Virginia, kann@INC
enthält benutzerdefinierten Code Perl und nicht nur Verzeichnisnamen, wie in When ist ein Subroutinenreferenz in @INC genannt? ).
Andere Tipps
Zusätzlich zu den oben aufgeführten Stellen, auch die OS X-Version von Perl hat zwei weitere Möglichkeiten:
-
Die /Library/Perl/x.xx/AppendToPath Datei. Pfade in dieser Datei aufgelistet sind @INC zur Laufzeit angehängt.
-
Die /Library/Perl/x.xx/PrependToPath Datei. Pfade in dieser Datei aufgeführt sind, vorangestellt @INC zur Laufzeit.
Wie hieß es, bereits @INC ist ein Array und Sie sind frei, alles zu addieren, die Sie wollen.
Ihr CGI-Skript REST sieht aus wie:
#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);
Unterprogramm weg von Rest.pm exportiert wird.