Perl使用/要求绝对路径吗?

7
如果我有一个.pm文件,有没有一种方法可以在不将其放置在我的@INC路径上的情况下使用它?在我的特定用例中,使用绝对路径或添加此目录到@INC不如这样清晰。

编辑:澄清:

我希望避免迭代@INC中的每个项目的必要性,而是直接指定我感兴趣的文件。例如,Node.JS中,require('something')将搜索路径列表,但require('/specific/something')将直接进入我告诉它去哪里的地方。在Perl中,我不确定这是否是在require中找到的相同功能,但它似乎有效。但是,use语句需要裸字。这使我有点困惑如何输入绝对路径。

在使用use module之前,加上use lib语句会更适合你的情况。但是为什么不能使用require呢?它更适合你的问题。此外,你还可以在Apache配置中设置SetEnv PERL5LIB环境变量,以将该目录应用于整个项目或应用程序。 - user966588
我需要引用一个 .pm 文件。虽然我还没有尝试过,但似乎它不会正常工作。通常我使用 CGI::ReadParse();use CGI ':cgi'; 这样的语法来调用模块中的函数。我不知道如何在 .pm 文件中使用 require 来实现这一点,但如果我能够使用 require 来实现这一点,那确实可以解决我的问题。 - 700 Software
它可以工作。尝试这样做 require "Newmodule.pm"; 然后调用 Newmodule::subname();。它可以正常执行。 - user966588
5个回答

7
您可以使用以下内容:
use lib '/path/to/Perl_module_dir'; # can be both relative or absolute
use my_own_lib;

您可以自行修改@INC(暂时,不需要担心,这也是use lib所做的):
BEGIN{ @INC = ( '/path/to/Perl_module_dir', @INC ); } # relative or absolute too
use my_own_lib;

后者与 use lib 的功能非常相似,只不过它使用 unshift 而不是 pop 来确保在同名模块的任何其他内容之前拾取您自己的模块。 - Borodin
将编辑后的POST推到数组开头。 - Gilles Quénot
2
如果这个模块是你的工作目录,把它放在和你的程序相同的目录下就没问题。但是默认情况下“. != dirname <program>”。 - pavel
1
只有当“.”在@INC中时才有效(在污点模式下不适用;对于省略它以提高安全性的发行版也不适用)。 - ysth
最后一条评论是错误的。Perl不会在脚本目录中查找模块。它通常会在“.”中查找,但并非总是如此,“.”通常是脚本目录,但远非总是如此。 - ikegami
显示剩余2条评论

4
根据评论中的讨论,我建议直接使用require。就像下面这样:
require "pathto/module/Newmodule.pm";

Newmodule::firstSub();

还有其他选项可用,如下:

  • use lib 'pathto/module'; 您需要将此行添加到希望在其中使用该模块的每个文件中。

use lib 'pathto/module';
use Newmodule;

  • using PERL5LIB environment variable. Set this on command line using export or add this to ~/.bashrc so that with every login it will be added to your @INC. Remember PERL5LIB adds directory before all @INC directories. So it will be used first. Also you can set it in apache httpd.conf using

    SetEnv PERL5LIB /fullpath/to/module
    
  • Or set it in BEGIN block.


1
一般来说,设置PERL5LIB环境变量。
export PERL5LIB=/home/ikegami/perl/lib

如果要安装相对于脚本的目录中的模块,请使用以下内容:
use FindBin qw( $RealBin );
use lib $RealBin;
  # or
use lib "$RealBin/lib";
  # or
use lib "$RealBin/../lib";

这将正确处理指向脚本的符号链接。
$ mkdir t

$ cat >t/a.pl
use FindBin qw( $RealBin );
use lib $RealBin;
use Module;

$ cat >t/Module.pm
package Module;
print "Module loaded\n";
1;

$ ln -s t/a.pl

$ perl a.pl
Module loaded

0

您可以使用Module::Load模块

use Module::Load;
load 'path/to/module.pm';

没有迹象表明他想在运行时加载模块,因此您需要在 BEGIN 中包装该模块。它也没有提供导入符号的方法,因此您还需要在 BEGIN 块中添加一个调用 import 的语句。总体而言,这对于 OP 想要做的事情来说是一个不好的解决方案。 - ikegami

0

FindBin::libs就能解决问题:

# search up $FindBin::Bin looking for ./lib directories
# and "use lib" them.

use FindBin::libs;

它使用FindBin::libs使用$FindBin:Bin而不是$FindBin:RealBin,因此在使用符号链接到脚本时无法工作 :( - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接