2009-09-23 86 views
10

我不知道如何在Perl中做一件事,我覺得我正在做一些根本錯誤的事情。如何加載相對於模塊路徑的文件?

我做一個大項目,所以我分裂任務分爲不同模塊。我將這些模塊放入項目目錄的「modules /」子目錄中,並將此目錄添加到PERL5LIB和PERLLIB。

所有這些模塊使用一些配置,保存在主項目目錄外部文件 - 「../configure.yaml」如果你看它從模塊文件的觀點。

但是,現在,當我通過使用模塊「使用」,模塊中的所有相對路徑被當作使用這些模塊,而不是從模塊本身的目錄腳本的當前目錄。甚至沒有使用FindBin或任何東西。

如何加載一個文件,從模塊的相對路徑?這甚至可能/明智嗎?

回答

13

Perl的專賣店裏模塊從在%INC散列加載。您可以加載的東西相對於:

package Module::Foo; 
use File::Spec; 
use strict; 
use warnings; 

my ($volume, $directory) = File::Spec->splitpath($INC{'Module/Foo.pm'}); 
my $config_file = File::Spec->catpath($volume, $directory, '../configure.yaml'); 

%INC的關鍵是基於對::嚴格的平移/與.pm後綴追加,即使在 的Windows,VMS等

注意,如果將相關目錄放在@INC中,%INC的值可能與當前目錄相關,因此如果在require/use和%INC之間更改目錄,請小心。

+0

並且也謝謝你。 – 2009-09-23 01:48:35

-3

更改您的use Module致電require Module(或require Module; Module->import(LIST))。然後使用調試器遍歷模塊加載過程,並查看Perl認爲它是從哪裏加載文件。

+2

好,我不認爲在我的程序中的錯誤 - 我只是不知道,怎麼寫:)如果我只是寫,例如,LoadFile(「../ configure.yaml」);插入到模塊中,然後在其他地方的腳本中使用THAT模塊,Perl僅將它用作腳本文件的相對路徑,而不是模塊文件。需求或調試不是真的有幫助,我知道問題出在哪裏,我只是不知道該怎麼辦 – 2009-09-23 01:28:11

8

全球%INC表包含每個模塊的條目use'd或require'd,與Perl發現該模塊的位置相關聯。

use YAML; 
print $INC{"YAML.pm"}; 

>> /usr/lib/perl5/site_perl/5.8/YAML.pm 

更有幫助?

+0

是的,這是......謝謝:) – 2009-09-23 01:44:35

9

有一個叫File::ShareDir模塊存在解決這個問題。你在正確的軌道上嘗試FindBin,但FindBin總是找到正在運行的程序,而不是使用它的模塊。 ShareDir的做法與ysth的解決方案非常相似,只是包裝在一個漂亮的界面中。

用法很簡單,只要

my $filename = File::ShareDir::module_file(__PACKAGE__, 
    'my/data.txt'); 
# and then open $filename or whatever else. 

my $dirname = File::ShareDir::module_dir(__PACKAGE__); 
# Play ball!