如何在不同的目录中包含Perl模块?

46 perl module

如何在不同的目录中包含Perl模块?它需要是包含它的模块的相对路径.

我试过了

push ( @INC,"directory_path/more_path");
Run Code Online (Sandbox Code Playgroud)

push ( @INC,"directory_path\\more_path");
Run Code Online (Sandbox Code Playgroud)

And*_*mar 69

编辑:首先提出正确的解决方案,最初来自这个问题.它是唯一一个相对于模块目录进行搜索的人:

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

还有许多其他方法可以搜索相对于当前目录的库.您可以使用-I参数调用perl,传递另一个模块的目录:

perl -I.. yourscript.pl
Run Code Online (Sandbox Code Playgroud)

您可以在perl脚本的顶部附近添加一行:

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

您可以在运行脚本之前修改环境变量PERL5LIB:

export PERL5LIB=$PERL5LIB:..
Run Code Online (Sandbox Code Playgroud)

推送(@INC)策略也可以工作,但它必须包含在BEGIN {}中,以确保在模块搜索之前运行推送:

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


dao*_*oad 14

很可能你的推动不起作用的原因是执行顺序.

use是一个编译时指令.你push在执行时完成:

push ( @INC,"directory_path/more_path");
use Foo.pm;  # In directory path/more_path
Run Code Online (Sandbox Code Playgroud)

您可以使用BEGIN块来解决此问题:

BEGIN {
    push ( @INC,"directory_path/more_path");
}
use Foo.pm;  # In directory path/more_path
Run Code Online (Sandbox Code Playgroud)

IMO,它是最清晰的,因此最好use lib:

use lib "directory_path/more_path";
use Foo.pm;  # In directory path/more_path
Run Code Online (Sandbox Code Playgroud)

有关BEGIN和其他特殊块以及执行时的信息,请参阅perlmod.

编辑

为了加载相对于您的脚本/库的代码,我强烈赞同File :: FindLib

您可以说use File::FindLib 'my/test/libs';在路径中的脚本上方的任何位置查找库目录.

说你的工作结构如下:

   /home/me/projects/
    |- shared/
    |   |- bin/
    |   `- lib/
    `- ossum-thing/
       `- scripts 
           |- bin/
           `- lib/
Run Code Online (Sandbox Code Playgroud)

在脚本里面ossum-thing/scripts/bin:

use File::FindLib 'lib/';
use File::FindLib 'shared/lib/';
Run Code Online (Sandbox Code Playgroud)

将找到您的库目录并将其添加到您的@INC.

创建一个包含运行工具套件所需的所有环境设置的模块,并将其加载到项目中的所有可执行文件中也很有用.

use File::FindLib 'lib/MyEnvironment.pm'
Run Code Online (Sandbox Code Playgroud)


bed*_*wyr 10

'use lib'也可以采用单个字符串值...

#!/usr/bin/perl
use lib '<relative-path>';
use <your lib>;
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 7

来自perlfaq8:


如何将程序所在的目录添加到模块/库搜索路径中?

(由brian d foy提供)

如果您已经知道该目录,则可以像在任何其他目录中一样将其添加到@INC.如果在编译时知道目录,则可以使用lib:

use lib $directory;
Run Code Online (Sandbox Code Playgroud)

此任务的技巧是找到目录.在脚本执行任何其他操作(例如chdir)之前,您可以使用Perl附带的Cwd模块获取当前工作目录:

BEGIN {
    use Cwd;
    our $directory = cwd;
    }

use lib $directory;
Run Code Online (Sandbox Code Playgroud)

您可以使用$ 0的值执行类似的操作,该值保存脚本名称.这可能会保持相对路径,但rel2abs可以将其转换为绝对路径.一旦你有了

BEGIN {
    use File::Spec::Functions qw(rel2abs);
    use File::Basename qw(dirname);

    my $path   = rel2abs( $0 );
    our $directory = dirname( $path );
    }

use lib $directory;
Run Code Online (Sandbox Code Playgroud)

Perl附带的FindBin模块可能有效.它找到当前正在运行的脚本的目录并将其放在$ Bin中,然后您可以使用它来构建正确的库路径:

use FindBin qw($Bin);
Run Code Online (Sandbox Code Playgroud)