我正在阅读有关use
的文档。与
BEGIN{ require Namespace::NameOfModule; }
然后,perl解释器将加载模块,并将双冒号::
转换为系统路径的分隔符(如果我没记错的话,是UNIX /
和WINDOWS \\
)。我只是想知道,是否能够从根目录加载模块。因为在这种情况下,例如目录DateTime.pm
中的模块/home/nickname/dir
。可能是(根据双冒号规则)::home::nickname::dir
,这是错误的(就像它甚至看起来像可怕的包路径一样)。那么,如何甚至可以从根目录加载模块呢?并且默认情况下路径是否从当前目录开始? (那是来自perl脚本所在的目录),还是仅来自@INC
dirs?
答案 0 :(得分:5)
模块名称空间仅相对于@INC
目录。默认情况下,这些文件是根据Perl的安装位置设置的,包括privlib(与Perl一起安装的核心模块),sitelib(由CPAN客户端安装的模块)和vendorlib(由供应商包管理器安装的模块)以及特定于体系结构的版本这些中的每一个。 local::lib可能会添加其他@INC
目录,并且在Perl 5.26之前@INC
还包括.
(当前的工作目录),但这不是一个好主意。
在裸字包名称上调用use
或require
时,它将执行您描述的翻译(将::
转换为路径分隔符并附加.pm
),然后将其追加到@INC
中的每个目录中,直到找到文件为止。 (它还会检查.pmc
,但这很少相关。)文件中的package语句应与用于查找use
的导入组件的模块路径匹配。
您可以手动修改@INC
,但是最好使用以下机制之一进行修改,这样,如果存在特定于架构的版本和特定于版本的子目录,则将予以遵守。
这些选项仅应用于将绝对路径插入@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.