2010-02-01 19 views
9

Mam dwie różne wersje modułu Perla. Obecnie kluczowy skrypt wykorzystuje wersję modułu określoną przez zmienną środowiskową, a system opiera się na różnych zadaniach wykonywanych przez różnych użytkowników. Środowisko użytkownika określa, która wersja modułu Perla była używana.Jak dynamicznie zmieniać ścieżkę modułu Perla?

Teraz chciałbym zmienić to na wersję, która jest określona w skrypcie Perla, tj. W zależności od przekazanych opcji. Niestety, kod taki jak ten:

if ($new){ use lib "newdir"; } 
else{ use lib "olddir"; } 
use module; 

nie działa. Perl dodaje po prostu newdir, a następnie olddir do @INC, a następnie uruchamia skrypt.

Jak określić dynamicznie, który moduł ma być używany?

Odpowiedz

15

Musisz użyć BEGIN{} blok więc if - kod else zostanie uruchomiony w czasie kompilacji:

BEGIN { 
    if ($new) { unshift @INC, "newdir"; } 
    else {  unshift @INC, "olddir"; } 
} 
use module; 

Można również ustawić zmienną środowiskową PERL5LIB więc nie musiałby zrób taką konfigurację w skrypcie.

+0

Twój * dziwny * styl bracketingu pozostawił ci niezamknięty blok. (Teraz, aby rozpocząć wojnę bracketingową!) – Axeman

+0

Eek. Dzięki, Axeman. – mob

+1

Warto również wspomnieć, że "use lib" i bezpośrednie manipulowanie @INC nie zawsze są równoważnymi operacjami. Zobacz dokumentację, aby uzyskać więcej szczegółów. – jrockway

12

Na CPAN istnieje pragma only, która ułatwia instalację i używanie wielu wersji tego samego modułu.

3

Jeśli wolisz logikę w czasie wykonywania (na przykład, jeśli zmienna $ new jest produkowana w bardziej skomplikowany sposób, niż nie chcesz uruchamiać w bloku BEGIN), możesz użyć funkcji require() moduł w czasie wykonywania.

Ważną rzeczą do zapamiętania jest to, że

use Module; 
use ModuleWithExports qw(export1 export2); 

jest taka sama jak

BEGIN { require Module; Module->import() } 
BEGIN { 
    require ModuleWithExports; 
    ModuleWithExports->import('export1', 'export2'); 
} 

Oznacza to, że aby mieć swój bieg kodu w czasie wykonywania można po prostu mieć:

if ($new) { 
    unshift @INC, "newdir"; 
} 
else { 
    unshift @INC, "olddir"; 
} 
require module; 
module->import(); # if necessary 

Alternatywą do używania funkcji require() jest użycie modułu CPAN z modułu Module::Load.

Powiązane problemy