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

Fre*_*idt 51 perl module relative-path

我的脚本的父目录中有一个模块,我想'使用'它.

如果我做

use '../Foo.pm';
Run Code Online (Sandbox Code Playgroud)

我得到语法错误.

我试着这样做:

push @INC, '..';
use EPMS;
Run Code Online (Sandbox Code Playgroud)

并且..显然没有出现在@INC中

我要疯了!这有什么不对?

eph*_*ent 94

use 在编译时发生,所以这将工作:

BEGIN {push @INC, '..'}
use EPMS;
Run Code Online (Sandbox Code Playgroud)

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

use lib '..';
use EPMS;
Run Code Online (Sandbox Code Playgroud)

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

use FindBin;                     # locate this script
use lib "$FindBin::RealBin/..";  # use the parent directory
use EPMS;
Run Code Online (Sandbox Code Playgroud)

  • 通常你想做一个unshift,所以你的目录就在列表的前面.这样Perl就不必搜索所有@INC来查找它.:) (2认同)

bri*_*foy 20

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

  • 设置PERL5LIB,如perlrun中所述

  • 在命令行上使用-I开关,也在perlrun记录.您也可以使用PERL5OPT自动应用它,但如果要这样做,只需使用PERL5LIB即可.

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

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


小智 12

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

/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm
Run Code Online (Sandbox Code Playgroud)

然后我在哪里使用它们:

use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;
Run Code Online (Sandbox Code Playgroud)

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

push @array => $pushee;
Run Code Online (Sandbox Code Playgroud)

但这只是一个偏好问题.

  • 推送语法看起来非常混乱.它肯定指向错误的方式.从机械的角度来看.它和逗号一样吗?逗号对方向更加模糊,因此更好...... (3认同)

zig*_*don 7

'use lib'就是答案,就像之前提到的@ephemient一样.另一种选择是使用require/import而不是use.这意味着模块不会在编译时加载,而是在运行时加载.

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

如果EXPR是一个单词,则require将采用".pm"扩展名,并在文件名中将"::"替换为"/",以便加载标准模块.这种加载模块的方式不会有改变命名空间的风险.