perl:仅为当前范围更改@INC
perl: change @INC for current scope only
对 Perl 的 @INC 数组的修改对于单个范围来说似乎非常混乱。我想澄清一下,因为它似乎在与任何动态初始化对象的方法作斗争。
有人认为我可以将其定义为本地来解决这个问题。
根据手册,"local modifies the listed variables to be local to the enclosing block, file, or eval."
让我烦恼的部分是 "or" 部分。
问题:我想更改 @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,同时在之后的所有已解析文件中保持不变?
(我知道我可以取消移位,但最终可能会遍历几十个目录)
require(dirname(__FILE__) . '/foo/bar.pm');
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();
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
对 Perl 的 @INC 数组的修改对于单个范围来说似乎非常混乱。我想澄清一下,因为它似乎在与任何动态初始化对象的方法作斗争。
有人认为我可以将其定义为本地来解决这个问题。
根据手册,"local modifies the listed variables to be local to the enclosing block, file, or eval."
让我烦恼的部分是 "or" 部分。
问题:我想更改 @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,同时在之后的所有已解析文件中保持不变?
(我知道我可以取消移位,但最终可能会遍历几十个目录)
require(dirname(__FILE__) . '/foo/bar.pm');
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();
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