【问题标题】:Perl use/require abolute path?Perl 使用/需要绝对路径?
【发布时间】:2013-02-13 13:38:38
【问题描述】:

如果我有一个.pm 文件,有没有办法可以use 它而不将它放在我的@INC 路径上?我认为这在我的特定用例中会更清晰 - 比使用相对路径或将此目录添加到 @INC 更清晰。

编辑:澄清:

我希望避免遍历 @INC 中的每个项目的必要性,而是直接指定我感兴趣的文件。例如,在 Node.JS 中,require('something') 将搜索路径列表,但是require('/specific/something') 会直接去我告诉它的地方。

在 Perl 中,我不确定这与 require 中的功能是否相同,但它似乎可以工作。

但是,use 语句需要裸词。这让我对如何输入绝对路径感到有些困惑。

【问题讨论】:

  • use module 之前的 use lib 语句对于您的情况是正确的。但是你为什么不能使用require。它更适合您的问题。您也可以在 apache conf 中 SetEnv PERL5LIB 环境变量将该目录应用于整个项目或应用程序。
  • 我需要一个.pm 文件。我没有尝试过,但它似乎不会正常工作。我通常使用CGI::ReadParse();use CGI ':cgi'; 之类的语法调用模块中的函数。我不知道如何使用require.pm 文件做到这一点,但如果我能用require 做到这一点,它确实可以解决我的问题。
  • 它有效。像这样尝试require "Newmodule.pm";,然后致电Newmodule::subname();。它执行得很好。

标签: perl absolute-path


【解决方案1】:

你可以用这个:

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 以确保您自己的模块在任何其他同名模块之前被拾取。
  • POST 进行了相应的编辑以推送到数组的开头。
  • 将模块放在与您的程序相同的目录中,只有当这是您的工作目录时才能正常工作。 . != dirname <program> 默认情况下...
  • 并且仅在 .处于@INC 中(在污点模式下不正确;对于为了更安全而省略它的发行版则不正确)
  • 最后一条评论是假的。 Perl 不会在脚本目录中查找模块。它通常查找.,但并非总是如此,.经常是脚本的目录,但远非总是。
【解决方案2】:

根据 cmets 中的讨论,我建议使用 require 本身。如下所示,

require "pathto/module/Newmodule.pm";

Newmodule::firstSub();

您也可以使用以下其他选项

  • use lib 'pathto/module'; 这行需要添加到您要使用该模块的每个文件中。

使用 lib 'pathto/module';
使用新模块;

  • 使用PERL5LIB 环境变量。使用导出在命令行上设置它或将其添加到~/.bashrc,以便每次登录时都会将其添加到您的@INC。记住 PERL5LIB 在所有 @INC 目录之前添加目录。所以会先用。您也可以使用

    在 apache httpd.conf 中设置它
    SetEnv PERL5LIB /fullpath/to/module
    
  • 或者设置在BEGIN块中。

【讨论】:

    【解决方案3】:

    一般来说,设置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
    

    【讨论】:

      【解决方案4】:

      您可以使用Module::Load 模块

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

      【讨论】:

      • 没有迹象表明他想在运行时加载模块,因此您可以将模块包装在BEGIN 中。它也不提供导入符号的方法,因此您还必须在 BEGIN 块中添加对 import 的调用。对于 OP 想要做的事情来说,这是一个糟糕的解决方案。
      【解决方案5】:

      FindBin::libs 成功了:

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

      【讨论】:

      • 它使用 FindBin::libs 使用 $FindBin:Bin 而不是 $FindBin:RealBin,因此在使用脚本的符号链接时它不起作用:(
      猜你喜欢
      • 1970-01-01
      • 2014-03-23
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多