如何在不在@INC中的目录中“使用”Perl模块?

时间:2008-10-08 22:08:54

标签: perl module relative-path

我的脚本的父目录中有一个模块,我想“使用”它。

如果我这样做

use '../Foo.pm';

我收到语法错误。

我试着这样做:

push @INC, '..';
use EPMS;

和..显然没有出现在@INC

我疯了!这有什么不对?

7 个答案:

答案 0 :(得分:88)

use发生在编译时,所以这可行:

BEGIN {push @INC, '..'}
use EPMS;

但更好的解决方案是use lib,这是一种更好的写作方式:

use lib '..';
use EPMS;

如果您从不同的目录运行,建议使用FindBin

use FindBin;                     # locate this script
use lib "$FindBin::RealBin/..";  # use the parent directory
use EPMS;

答案 1 :(得分:19)

您可以通过多种方式修改@INC

  • 设置PERL5LIB,如perlrun

  • 中所述
  • 在命令行中使用-I开关,也在perlrun中记录。你也可以使用PERL5OPT自动应用它,但如果要这样做,只需使用PERL5LIB。

  • 程序中的
  • use lib,虽然这很脆弱,因为另一台机器上的另一个人可能将它放在不同的目录中。

  • 手动修改@INC,确保在编译时执行此操作,如果您想使用use引入模块。这太过分了。

答案 2 :(得分:12)

我个人更喜欢将我的模块(我为自己编写的模块或我可以控制的系统)保存在某个目录中,并将它们放在子目录中。如:

/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm

然后我在哪里使用它们:

use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;

顺便说一句......当谈到推动时,我更喜欢胖箭头逗号:

push @array => $pushee;

但这只是一个偏好问题。

答案 3 :(得分:6)

'use lib'是答案,正如前面提到的@ephemient所说的那样。另一种选择是使用require / import而不是use。这意味着模块不会在编译时加载,而是在运行时加载。

这将允许您在尝试时修改@INC,或者您可以传递需要路径到文件而不是模块名称。来自'perldoc -f require':

  

如果EXPR是一个单词,则require将采用“.pm”扩展名和   用文件名中的“/”替换“::”,以便于使用   加载标准模块。这种模块加载形式没有风险   改变命名空间。

答案 4 :(得分:2)

您必须在push之前处理use并提前处理use。所以,我相信你需要BEGIN { push @INC, ".."; }才有机会。

答案 5 :(得分:1)

据“perldoc -f use”报道:

  

完全等同于   BEGIN { require Module; import Module LIST; }
  除了模块必须是一个单词。

换句话说,“使用”相当于:

  • 在编译时运行,
  • 将包名称转换为文件名
  • require - 该文件名和
  • import - 该包裹。

因此,您可以在BEGIN块中调用require和import,而不是调用use:

BEGIN {
  require '../EPMS.pm';
  EPMS->import();
}

当然,如果您的模块在调用import时实际上没有进行任何符号导出或其他初始化,您可以将该行保留:

BEGIN {
  require '../EPMS.pm';
}

答案 6 :(得分:0)

某些 IDE 无法与“use lib”(最受欢迎的答案)一起正常工作。我发现“use lib::relative”适用于我的 IDE、JetBrains 的 WebStorm。

POD for lib::relative