2010-02-01 57 views
9

我有兩個不同版本的Perl模塊。目前,關鍵腳本使用由環境變量指定的模塊版本,並且系統依賴於由不同用戶運行的不同任務。用戶的環境將決定使用哪個版本的Perl模塊。如何動態更改Perl模塊路徑?

現在我想將其更改爲在Perl腳本中指定的版本,即根據傳遞的選項而定。不幸的是,這樣的代碼:

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

不起作用。 Perl只需附加newdir,然後olddir@INC然後運行該腳本。

如何動態指定要使用哪個模塊?

回答

15

您需要使用BEGIN{}塊讓你if - else代碼將在編譯時運行:

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

您還可以設置PERL5LIB環境變量,所以你就不必在腳本中進行這種配置。

+0

你的*怪異*包圍風格給你留下了一個未封閉的塊。 (現在,開始包圍戰爭!) – Axeman 2010-02-01 20:51:24

+0

Eek。謝謝Axeman。 – mob 2010-02-01 21:02:32

+1

另外值得一提的是,「使用lib」和直接操作@INC並不總是等效的操作。有關更多詳細信息,請參閱文檔。 – jrockway 2010-02-02 04:51:55

12

CPAN上有一個only編譯指示,使安裝和使用同一模塊的多個版本變得簡單。

3

如果您寧願讓您的邏輯在運行時發生(例如,如果$ new變量是以更復雜的方式生成的,您不想在BEGIN塊中運行),則可以使用require()加載運行時模塊。

要記住的重要一點是,

use Module; 
use ModuleWithExports qw(export1 export2); 

相同

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

這意味着,有你的代碼運行在運行時,你可以簡單的有:

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

使用require()的另一種方法是使用CPAN中的Module::Load模塊。