Wie wird Perl @INC aufgebaut? (Aka Was sind alle Möglichkeiten zu beeinflussen, wo Perl-Module gesucht werden?)

StackOverflow https://stackoverflow.com/questions/2526804

  •  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.

War es hilfreich?

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.

  1. Standard @INC

    Perl-Interpreter mit einem bestimmten @INC Standardwert zusammengestellt. Um diesen Wert zu ermitteln, führte env -i perl -V Befehl (env -i ignoriert die PERL5LIB 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

  1. Umgebungsvariable PERL5LIB (oder PERLLIB)

    Perl pre-pends mit einer Liste von Verzeichnissen @INC (Kolon-getrennt) in PERL5LIB enthalten (wenn es nicht definiert ist, PERLLIB verwendet wird) Umgebungsvariablen der Shell. Um den Inhalt von @INC nach PERL5LIB und PERLLIB Umgebungsvariablen genommen hat Wirkung, Lauf perl -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
     .
    
  2. -I Befehlszeilenoption

    Perl 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 (oder PERLOPT) Umgebungsvariablen (siehe Kapitel 19.02 in Programming Perl )

  3. Direkt über den lib Pragma

    Perl pre-pends @INC mit einer Liste von Verzeichnissen, um es über use 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 über no lib .

  4. Sie können direkt @INC als regulären Perl-Array manipulieren.

    . Hinweis: Da @INC bei der Erstellung Phase verwendet wird, dies erfolgt innerhalb eines BEGIN {} Block sein muss, die die use 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:

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 Verbraucher PERL5LIB, 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 von use lib / no lib Pragmas zu implementieren, verwenden Sie dann direkt @INC Manipulation innerhalb BEGIN {} 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:

  1. Die /Library/Perl/x.xx/AppendToPath Datei. Pfade in dieser Datei aufgelistet sind @INC zur Laufzeit angehängt.

  2. 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top