如何在Perl中加载不在@INC中的路径的模块?
我已经阅读了有关如何添加@INC路径的答案,但问题是必须在代码开头更改@INC。编译完成后,我遇到的所有模块都会查找@INC以查找模块的位置。我的问题是我们试图将所有这些环境特定的东西分离到配置文件中。如果它在配置文件中,则需要先读取路径才能将其推送到@INC,但是代码已经编译好了,似乎无法修改@INC。
答案 0 :(得分:8)
Perl有一个增量编译模型,这意味着可以在解析其他代码之前执行代码。为此,我们可以使用阶段块(又名。阶段):
BEGIN {
print "This is executed as soon as the block has been parsed\n";
}
这样的相位块也可用于加载配置文件。
例如,use
语句实际上是BEGIN
块的语法糖。
use Foo::Bar qw/baz qux/;
相当于
BEGIN {
require Foo::Bar; # or: require "Foo/Bar.pm";
Foo::Bar->import(qw/baz qux/);
}
我们也可以在运行时加载模块,尽管这只适用于面向对象的模块。
所以我们有三个选择:
BEGIN
阶段加载配置,并在加载实际模块之前添加正确的库路径BEGIN
期间手动加载模块及其完整路径(例如require "/my/modules/Foo/Bar.pm"
使用裸require
相当不舒服,这就是Module::Runtime
存在的原因
答案 1 :(得分:3)
使用BEGIN
块加载您的自定义@INC
位置,然后use lib
加载它。
# use lib /a special directory/
BEGIN {
my $lib_to_include = ...;
require lib;
lib->import($lib_to_include);
}
use Module_That_Requires_Special_Dir;
唯一需要注意的是,无论用于加载自定义包含目录的代码,都必须依赖于此BEGIN
块之前已定义的方法。因此,您无法使用稍后在文件中的子例程。
答案 2 :(得分:0)