perl:仅将@INC更改为当前范围

时间:2015-08-28 22:00:20

标签: perl oop perl-module mod-perl mod-perl2

修改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,然后在所有已解析的文件中保留原样吗?

(我知道我可以卸下,但最终可能会有几十个可以遍历的目录)

3 个答案:

答案 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();