2009-08-18 28 views
5

Nella mia app, ho inserito tutti i moduli in una directory, chiamiamolo semplicemente libx. Dato che spetta all'utente scegliere dove distribuire l'app, non voglio hardcriptare il percorso lib.Perché "lib lib" non ha effetto in questo modo?

Quindi all'inizio di myapp.pl, ho scritto le seguenti righe di codice.

#! /usr/bin/perl -w 
use strict; 

my $curr_dir = $0; 
my $curr_lib = $curr_dir; 
$curr_lib =~ s/myapp\.pl/libx/; 

use $curr_lib ; 

Invece di ottenere quello che mi aspetto, ho ottenuto errori di compilazione!

Quindi cosa c'è di sbagliato nel mio codice? Non voglio hardcode il percorso di lib quando si utilizza use lib, come devo fare questo?


Scusa se ho dimenticato di dire che quando l'applicazione viene distribuita, myapp.pl e libx sono nella stessa directory.

risposta

15

l'utilizzo avviene in fase di compilazione, non in fase di esecuzione, quindi la variabile non è stata ancora impostata. Si può fare:

my $curr_lib; 
BEGIN { 
    $curr_lib = $0; 
    $curr_lib =~ s/myapp\.pl/libx/; 
}  
use lib $curr_lib; 

Oppure si potrebbe:

use FindBin; 
use lib "$FindBin::Bin/libx"; 
2

Ho avuto problemi anche con questo. Quello che sta succedendo è che Perl esegue due passaggi sul codice: una volta per compilarlo, e la seconda volta per eseguirlo. Nell'esempio, le linee 4,5 e 6 non vengono eseguite fino al runtime, ma l'use diventa effettiva durante la compilazione.

Una possibilità è mettere tutto all'interno di un blocco BEGIN{}, che eseguirà il codice in fase di compilazione. L'ho fatto, ma è disordinato/brutto. (A differenza di $0, è necessario utilizzare $ARGV[0] in Perl).

Il modo migliore per dire a Perl dove raccogliere le librerie è utilizzare il flag -I. Si può mettere sulla linea #!, o se si avvia lo script da un altro script, è possibile avviarlo come

 
perl -I/your/directory/libx your_script.pl 

È percorsi relativi può uso, quindi forse

 
perl -I./libx script.pl 

sarebbe Lavoro per te.

+0

Sarebbe utile se ci dicesse esattamente come pensi che il tuo utente possa avviare l'app. Scriveranno semplicemente "myapp".pl ', e sta a loro avere $ PATH set in modo che myapp.pl possa essere trovato in qualunque directory lo abbiano bloccato? –

1

use xxx è un fase di compilazione direttiva, non un'istruzione run-time. Non è possibile impostarlo a livello di codice all'interno dello script che si sta eseguendo.

Potrebbe essere necessario provare require rather than use

Se avete bisogno di use, è necessario impostare la variabile $PERL5LIB ambiente per garantire i moduli si trovano e utilizzati correttamente, o cambiare la tua shebang leggere #! /usr/local/perl -w -I/path/to/libx. Esistono altri metodi (local::lib ecc.), Ma dalla tua domanda sembra che il tuo controllo sull'installazione sia un po 'limitato per quel tipo di approccio.

+1

Questo non è vero al 100%, puoi usare una stringa 'eval' per eseguire un' uso' in fase di esecuzione. –