如何加载相对于模块路径的文件?

时间:2009-09-23 00:52:58

标签: perl deployment module

我不知道如何在Perl中做一件事,我觉得我在做一些根本错误的事情。

我正在做一个更大的项目,所以我将任务分成不同的模块。我将模块放入项目目录的“modules /”子目录中,并将此目录添加到PERL5LIB和PERLLIB。

所有这些模块都使用一些配置,保存在主项目目录的外部文件中 - “../configure.yaml”,如果从模块文件的角度来看它。

但是,现在,当我通过“use”使用模块时,模块中的所有相对路径都是从使用这些模块的脚本的当前目录获取的,而不是从模块本身的目录中获取。甚至在我使用FindBin或其他任何东西时都没有。

如何从模块路径加载文件?这甚至可能/可取吗?

4 个答案:

答案 0 :(得分:14)

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的密钥基于:: to / with .pm附加的严格翻译,甚至是 Windows,VMS等

请注意,如果将相对目录放在@INC中,%INC中的值可能相对于当前目录,因此如果在require / use和check%INC之间更改目录,请小心。

答案 1 :(得分: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!

答案 2 :(得分:8)

全局%INC表包含每个模块的条目use'或require'd,与Perl找到该模块的位置相关联。

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

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

这更有帮助吗?

答案 3 :(得分:-3)

use Module来电更改为require Module(或require Module; Module->import(LIST))。然后使用调试器逐步完成模块加载过程,看看Perl认为它从哪里加载文件。