Come è costruito @INC di Perl?(ovvero quali sono tutti i modi per influenzare il luogo in cui vengono cercati i moduli Perl?)

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

  •  22-09-2019
  •  | 
  •  

Domanda

Quali sono tutti i modi che influenzano il luogo in cui vengono cercati i moduli Perl?O, Come è costruito @INC di Perl?

Come sappiamo, Perl utilizza @INC array contenente i nomi delle directory per determinare dove cercare i file dei moduli Perl.

Non sembra esserci un post completo di tipo FAQ "@INC" su StackOverflow, quindi questa domanda è intesa come tale.

È stato utile?

Soluzione

Vedremo come il contenuto di questo array è costruito e come può essere manipolato per influenzare dove l'interprete Perl troverà i file del modulo.

  1. Predefinito @INC

    L'interprete Perl lo è compilato con uno specifico @INC valore di default.Per scoprire questo valore, esegui env -i perl -V comando (env -i ignora il PERL5LIB variabile ambientale - vedi #2) e nell'output vedrai qualcosa del genere:

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

Nota . alla fine;questa è la directory corrente (che non è necessariamente la stessa directory dello script).Manca in Perl 5.26+ e quando Perl viene eseguito con -T (controlli di contaminazione abilitati).

Per modificare il percorso predefinito durante la configurazione della compilazione binaria Perl, impostare l'opzione di configurazione otherlibdirs:

Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3

  1. Variabile ambientale PERL5LIB (O PERLLIB)

    Perl è pre-pendente @INC con un elenco di directory (separate da due punti) contenute in PERL5LIB (se non è definito, PERLLIB viene utilizzata) variabile d'ambiente della tua shell.Per vedere il contenuto di @INC Dopo PERL5LIB E PERLLIB le variabili di ambiente hanno avuto effetto, esegui 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 opzione della riga di comando

    Perl è pre-pendente @INC con un elenco di directory (separate da due punti) passato come valore di -I opzione della riga di comando.Questo può essere fatto in tre modi, come al solito con le opzioni Perl:

    • Passalo dalla riga di comando:

      perl -I /my/moduledir your_script.pl
      
    • Passalo tramite la prima riga (shebang) del tuo script Perl:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • Passalo come parte di PERL5OPT (O PERLOPT) variabile d'ambiente (vedi capitolo 19.02 in Programmazione Perl)

  3. Passalo tramite il lib pragma

    Perl è pre-pendente @INC con un elenco di directory passate ad esso tramite use lib.

    In un programma:

    use lib ("/dir1", "/dir2");
    

    Sulla riga di comando:

    perl -Mlib=/dir1,/dir2
    

    Puoi anche rimuovere le directory da @INC attraverso no lib.

  4. Puoi manipolare direttamente @INC come un normale array Perl.

    Nota:Da @INC viene utilizzato durante la fase di compilazione, questa deve essere fatta all'interno di a BEGIN {} blocco, che precede il use MyModule dichiarazione.

    • Aggiungi directory all'inizio tramite unshift @INC, $dir.

    • Aggiungi directory alla fine tramite push @INC, $dir.

    • Fai qualsiasi altra cosa che puoi fare con un array Perl.

Nota:Le directory sono immutabile su @INC nell'ordine elencato in questa risposta, ad es.predefinito @INC è l'ultimo dell'elenco, preceduto da PERL5LIB, preceduto da -I, preceduto da use lib e diretto @INC manipolazione, gli ultimi due mescolati nell'ordine in cui si trovano nel codice Perl.

Riferimenti:

Non sembra esserci una soluzione completa @INC Post di tipo FAQ su Stack Overflow, quindi questa domanda è intesa come tale.

Quando utilizzare ciascun approccio?

  • Se i moduli in una directory devono essere utilizzati da molti/tutti gli script sul tuo sito, in particolare eseguiti da più utenti, quella directory dovrebbe essere inclusa nell'impostazione predefinita @INC compilato nel binario Perl.

  • Se i moduli nella directory saranno usati esclusivamente da un utente specifico per tutti gli script che l'utente esegue (o se ricompilare Perl nonèun'opzione per cambiare le impostazioni predefinite @INC nel caso d'uso precedente), impostare gli utenti PERL5LIB, solitamente durante l'accesso dell'utente.

    Nota:Si prega di essere consapevoli delle solite insidie ​​​​delle variabili di ambiente Unix, ad es.in alcuni casi l'esecuzione degli script come un particolare utente non garantisce la loro esecuzione con l'ambiente di quell'utente configurato, ad es.attraverso su.

  • Se i moduli nella directory devono essere utilizzati solo in circostanze specifiche (es.quando gli script vengono eseguiti in modalità sviluppo/debug, è possibile impostare PERL5LIB manualmente o passare il file -I opzione perl.

  • Se i moduli devono essere utilizzati solo per script specifici, by Tutto gli utenti che li utilizzano, utilizzano use lib/no lib pragma nel programma stesso.Dovrebbe essere utilizzato anche quando la directory da cercare deve essere determinata dinamicamente durante il runtime, ad es.dai parametri della riga di comando dello script o dal percorso dello script (vedere il file TrovaBin modulo per un caso d'uso molto interessante).

  • Se le directory in @INC devono essere manipolati secondo una logica complicata, impossibile o troppo ingombrante da implementare mediante una combinazione di use lib/no lib pragma, quindi utilizzare direct @INC manipolazione all'interno BEGIN {} blocco o all'interno di una libreria per scopi speciali designata per @INC manipolazione, che deve essere utilizzata dai tuoi script prima che venga utilizzato qualsiasi altro modulo.

    Un esempio di ciò è il passaggio automatico tra le librerie nelle directory prod/uat/dev, con il prelievo della libreria a cascata in prod se manca da dev e/o UAT (l'ultima condizione rende la soluzione standard "usa lib + FindBin" piuttosto complicata.Un'illustrazione dettagliata di questo scenario è disponibile in Come posso utilizzare i moduli Perl beta dagli script Perl beta?.

  • Un ulteriore caso d'uso per la manipolazione diretta @INC è poter aggiungere riferimenti a subroutine o riferimenti a oggetti (sì, Virginia, @INC può contenere codice Perl personalizzato e non solo nomi di directory, come spiegato in Quando viene chiamato un riferimento a una subroutine in @INC?).

Altri suggerimenti

In aggiunta alle posizioni di cui sopra, la versione OS X di Perl ha anche altri due modi:

  1. Il file /Library/Perl/x.xx/AppendToPath. Percorsi elencati in questo file vengono aggiunti alla @INC in fase di esecuzione.

  2. Il file /Library/Perl/x.xx/PrependToPath. Percorsi elencati in questo file sono preceduti da @INC in fase di esecuzione.

Come è stato detto già @INC è un array e tu sei libero di aggiungere tutto quello che vuoi.

Il mio script CGI REST appare come:

#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
    push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);

subroutine passata viene esportato dal Rest.pm.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top