我正在阅读有关use. 它与
BEGIN{ require Namespace::NameOfModule; }
Run Code Online (Sandbox Code Playgroud)
perl 解释器加载模块并将双冒号转换::为系统路径的分隔符(UNIX/和 WINDOWS \\,如果我没记错的话)。我只是想知道,如果我能够从 root 加载模块。因为在那种情况下,例如DateTime.pmdir 中的模块/home/nickname/dir。它将是(根据双冒号规则)::home::nickname::dir,这是错误的(就像它甚至应该看起来像可怕的包路径)。那么如何 - 如果甚至 - 可以从根目录加载模块?并且路径是否默认从当前目录开始?(即来自 dir 的 perl 脚本所在的位置),还是仅来自@INCdirs?
模块命名空间@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';
Run Code Online (Sandbox Code Playgroud)
将自定义位置添加到 后@INC,将首先搜索该目录以查找任何进一步的use呼叫。
use Foo::Bar; # now checks /path/to/lib/Foo/Bar.pm first
# which should contain package Foo::Bar
Run Code Online (Sandbox Code Playgroud)