perl-软件包名称:我可以使用root的路径吗?

时间:2019-12-26 22:59:32

标签: perl module path

我正在阅读有关use的文档。与

相同
BEGIN{ require Namespace::NameOfModule; }

然后,perl解释器将加载模块,并将双冒号::转换为系统路径的分隔符(如果我没记错的话,是UNIX /和WINDOWS \\)。我只是想知道,是否能够从根目录加载模块。因为在这种情况下,例如目录DateTime.pm中的模块/home/nickname/dir。可能是(根据双冒号规则)::home::nickname::dir,这是错误的(就像它甚至看起来像可怕的包路径一样)。那么,如何甚至可以从根目录加载模块呢?并且默认情况下路径是否从当前目录开始? (那是来自perl脚本所在的目录),还是仅来自@INC dirs?

2 个答案:

答案 0 :(得分:5)

模块名称空间仅相对于@INC目录。默认情况下,这些文件是根据Perl的安装位置设置的,包括privlib(与Perl一起安装的核心模块),sitelib(由CPAN客户端安装的模块)和vendorlib(由供应商包管理器安装的模块)以及特定于体系结构的版本这些中的每一个。 local::lib可能会添加其他@INC目录,并且在Perl 5.26之前@INC还包括.(当前的工作目录),但这不是一个好主意。

在裸字包名称上调用userequire时,它将执行您描述的翻译(将::转换为路径分隔符并附加.pm),然后将其追加到@INC中的每个目录中,直到找到文件为止。 (它还会检查.pmc,但这很少相关。)文件中的package语句应与用于查找use的导入组件的模块路径匹配。

您可以手动修改@INC,但是最好使用以下机制之一进行修改,这样,如果存在特定于架构的版本和特定于版本的子目录,则将予以遵守。

  • lib-use lib '/path/to/lib';
  • -I-perl -I/path/to/lib ...
  • PERL5LIB-env PERL5LIB=/path/to/lib perl ...

这些选项仅应用于将绝对路径插入@INC中,因为相对路径将具有与以前使用的.相同的漏洞,因为当更改当前目录时,它们的含义可能有所不同。要在任意位置添加相对于脚本的路径,可以安装lib::relative来简化该过程,或者可以使用其核心文档来描述其等效功能。

use lib::relative '../lib';

将自定义位置添加到@INC后,将首先在该目录中搜索其他use调用。

use Foo::Bar; # now checks /path/to/lib/Foo/Bar.pm first
# which should contain package Foo::Bar

答案 1 :(得分:2)

即使您可以像这样加载模块,也会遇到许多其他问题。

  • 要找到package,模块的package ::home::nickname::dir::SomeModule;指令必须为import
  • 您必须使用::home::nickname::dir::SomeModule->some_method来调用静态方法。
  • 您必须使用::home::nickname::dir::SomeModule::some_sub来调用子项。

这显然是错误的方法。

对于相对于脚本安装在某个位置的模块,请在脚本中使用以下内容告诉perl看哪里:

use FindBin qw( $RealBin );
use lib "$RealBin/../lib";  # Or whatever.

对于为任何脚本使用而安装的模块,请使用以下环境变量:

export PERL5LIB="$HOME/dir"  # Or whatever.