显式设置@INC后使用lib pragma无效

时间:2017-04-20 12:53:55

标签: perl

use feature qw(say);
use strict;
use warnings;
BEGIN {
    @INC = qw(dir1 dir2); # <-- lib pragma works fine if I omit this line
    # @INC = ();  <-- this is what I wanted to do
    use lib 'dir3';
}
say for @INC;

输出

dir1
dir2

预期输出

dir3
dir1
dir2

2 个答案:

答案 0 :(得分:9)

(string) buffer语句包含在隐式use块中,并且 程序中的所有Perl BEGIN块在完成编译后立即执行

这意味着你在这里有嵌套的BEGIN块,并且因为内部的BEGIN语句 - 在语句的末尾完成编译,所以它是第一个被执行的。接下来是显式use lib 'dir3'块的右括号,它完成了 块的编译,然后只执行那些语句

以下是仅使用BEGIN语句的示例程序,并使用明确的say块替换原始语句中的use语句

BEGIN

输出

use strict;
use warnings;
use feature 'say';

BEGIN {

    say "outer BEGIN";

    BEGIN {
        say "inner BEGIN";
    }
}

您的代码就像您这样编写

一样
inner BEGIN
outer BEGIN

首先执行use feature qw(say); use strict; use warnings; use lib 'dir3'; BEGIN { @INC = qw(dir1 dir2); } say for @INC; ,将use lib添加到dir3,然后执行显式@INC块并完全覆盖BEGIN

如果您想首先清空@INC然后使用@INC语句添加它,那么您应该写

use lib

如果没有嵌套,BEGIN { our @INC = ( ); } use lib 'dir3'; 块将按程序中出现的顺序执行

答案 1 :(得分:-1)

来自perldoc - lib

  

这是一个简单的小模块,它简化了编译时对@INC的操作。

在左大括号之后和作业之前插入say for @INC;,例如

BEGIN {
    say for @INC;
    @INC = qw(dir1 dir2); # <-- lib pragma works fine if I omit this line
    # @INC = ();  <-- this is what I wanted to do
    use lib 'dir3';
}

您会看到列出dir3

perldoc - use

  

因为use在编译时生效,所以它不尊重正在编译的代码的普通流控制。

在执行任何其他操作之前,

dir3会插入@INC,然后会为@INC分配新值(dir1, dir2)。当您最终查看@INC时,您会看到这个新的指定值。