修改Perl的@INC数组对于单个范围而言似乎非常混乱。我想澄清一下,因为它似乎正在与任何动态初始化对象的方法作斗争。
有人会认为我可以将其定义为本地解决此问题。
根据手册,“local将列出的变量修改为封闭块,文件或eval的本地变量。”
令我讨厌的部分是“或”部分。
问题:在某些情况下,我想更改@INC数组以包含一个目录,并且只包含一个目录。
示例尝试和问题:
假设我有一个启动脚本index.pl:
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use File::Basename;
# Lets say I want to modify @INC here to look in ONLY one path. Local
# should allow us to declare for one scope or file (how non explicit this
# is annoys me) Since I have not defined a scope with brackets, it should
# be effective for the current file
local @INC = (dirname(__FILE__) . '/foo/'); #some relative path
# Lets say bar now uses standard perl modules
require 'bar.pm';
# ^- This will fail because local did not work as described, fails at use
# XML::Simple because it is traversing foo
my $bar = bar->new();
为了全面,这是一个bar.pm:
package bar;
use strict;
use warnings;
sub new
{
my $class = shift;
my $self = bless {}, $class;
use XML::Simple;
return $self;
}
1;
无论如何只修改当前文件的@INC,然后在所有已解析的文件中保留原样吗?
(我知道我可以卸下,但最终可能会有几十个可以遍历的目录)
答案 0 :(得分:2)
require(dirname(__FILE__) . '/foo/bar.pm');
答案 1 :(得分:2)
use File::Basename;
use subs 'require';
sub require {
my $module_file = shift;
die "unexpected absolute path $module_file\n" if $module_file =~ /^\//;
CORE::require(dirname(__FILE__) . '/foo/' . $module_file);
}
请参阅http://perldoc.perl.org/CORE.html#OVERRIDING-CORE-FUNCTIONS
答案 2 :(得分:0)
local @INC
有效,但您的bar.pm
文件仍需要能够找到XML/Simple.pm
(在编译文件时执行use
语句,无论是它出现在文件中的位置),可能来自原始@INC
,因此您的本地@INC
应该以原始@INC
的副本开头。
{
local @INC = (dirname(__FILE__) . '/foo/', @INC);
require 'bar.pm';
} # local @INC out of scope now, original @INC restored
my $bar = bar->new();