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

Perl 如何相对于模块路径加载文件?,perl,deployment,module,Perl,Deployment,Module,我不知道如何在Perl中做一件事,我觉得我在做一些根本错误的事情 我正在做一个更大的项目,所以我把任务分成了不同的模块。我将模块放入项目目录中的“modules/”子目录中,并将该目录添加到PERL5LIB和PERLLIB中 所有这些模块都使用一些配置,保存在主项目目录-“./configure.yaml”中的外部文件中,如果您从模块文件的角度来看 但是,现在,当我通过“use”使用模块时,模块中的所有相对路径都取自使用这些模块的脚本的当前目录,而不是来自模块本身的目录。甚至当我使用FindBi

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

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

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

但是,现在,当我通过“use”使用模块时,模块中的所有相对路径都取自使用这些模块的脚本的当前目录,而不是来自模块本身的目录。甚至当我使用FindBin或其他什么的时候都不会


如何从模块路径加载相对文件?这是否可行/可取?

将您的
使用模块
调用更改为
需要模块
(或
需要模块;模块->导入(列表)
)。然后使用调试器逐步完成模块加载过程,并查看Perl认为从何处加载文件。

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、虚拟机等


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

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

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

>> /usr/lib/perl5/site_perl/5.8/YAML.pm
这更有帮助吗?

有一个名为的模块可以解决这个问题。您尝试FindBin的方法是正确的,但是FindBin总是找到正在运行的程序,而不是正在使用它的模块。ShareDir做的事情与ysth的解决方案非常相似,只是包装在一个漂亮的界面中

用法非常简单

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


嗯,我认为我的程序中没有BUG——我只是不知道如何编写:)如果我只编写,例如LoadFile(“../configure.yaml”);在模块中,我在其他地方的脚本中使用该模块,Perl只是将其用作脚本文件的相对路径,而不是模块文件。要求或调试并没有真正的帮助,我知道问题在哪里,我只是不知道如何处理它
my $dirname = File::ShareDir::module_dir(__PACKAGE__);
# Play ball!