2009-09-23 51 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! 
相关问题