我的脚本的父目录中有一个模块,我想“使用”它。
如果我这样做
use '../Foo.pm';
我收到语法错误。
我试着这样做:
push @INC, '..';
use EPMS;
和..显然没有出现在@INC
中我疯了!这有什么不对?
答案 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
。
答案 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。