Come posso utilizzare un modulo Perl in una directory non in @INC?

Ho un modulo nella directory principale del mio script e vorrei “usarlo”.

Se lo faccio

use '../Foo.pm'; 

Ottengo errori di syntax.

Ho provato a fare:

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

e .. apparentemente non compare in @INC

Sto impazzendo! Cosa c’è che non va qui?

use avviene in fase di compilazione, quindi funzionerebbe:

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

Ma la soluzione migliore è use lib , che è un modo più bello di scrivere quanto sopra:

 use lib '..'; use EPMS; 

Nel caso in cui si stia eseguendo da una directory diversa, tuttavia, si consiglia di utilizzare FindBin :

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

Ci sono molti modi in cui puoi modificare @INC .

  • impostare PERL5LIB, come documentato in perlrun

  • usa l’ opzione -I sulla riga di comando, anch’essa documentata in perlrun . Puoi anche applicarlo automaticamente con PERL5OPT, ma usa PERL5LIB solo se hai intenzione di farlo.

  • use lib all’interno del tuo programma, anche se questo è fragile poiché un’altra persona su una macchina diversa potrebbe averla in una directory diversa.

  • Modificare manualmente @INC , assicurandosi di farlo al momento della compilazione se si desidera utilizzare un modulo. Questo è troppo lavoro però.

Personalmente preferisco mantenere i miei moduli (quelli che scrivo per me stesso o per i sistemi che posso controllare) in una certa directory, e anche per metterli in una sottodirectory. Come in:

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

E poi dove li uso:

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

Per inciso … quando si tratta di spingere, preferisco la virgola della freccia grassa:

 push @array => $pushee; 

Ma è solo una questione di preferenza.

‘use lib’ è la risposta, come @ephemient menzionato in precedenza. Un’altra opzione è usare require / import invece di use. Significa che il modulo non verrebbe caricato in fase di compilazione, ma in runtime.

Ciò ti consentirà di modificare @INC mentre ci hai provato, oppure potresti richiedere un percorso al file invece del nome del modulo. Da ‘perldoc -f require’:

Se EXPR è una parola chiave, il fabbisogno assume un’estensione “.pm” e sostituisce “::” con “/” nel nome del file per te, per semplificare il caricamento dei moduli standard. Questa forma di caricamento dei moduli non rischia di alterare il tuo spazio dei nomi.

È necessario che la push venga elaborata prima use e che l’ use venga elaborato in anticipo. Quindi, avrai bisogno di un BEGIN { push @INC, ".."; } BEGIN { push @INC, ".."; } avere una possibilità, credo.

Come riportato da “perldoc -f use”:

È esattamente equivalente a
BEGIN { require Module; import Module LIST; }
ad eccezione del fatto che il Modulo deve essere un bareword.

Mettendola in un altro modo, “usa” è equivalente a:

  • in esecuzione al momento della compilazione,
  • convertire il nome del pacchetto in un nome file,
  • require -ing quel nome di file, e
  • import -ing quel pacchetto.

Quindi, invece di chiamare use, puoi chiamare require e import all’interno di un blocco BEGIN:

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

E, naturalmente, se il tuo modulo non esegue effettivamente l’esportazione di simboli o altre inizializzazioni quando chiami l’importazione, puoi lasciare quella linea:

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