使用我们和BEGIN块交互声明的变量

时间:2016-05-14 14:33:22

标签: perl scoping lexical-scope

在这种情况下,为什么未初始化的变量的行为/交互方式与初始化变量不同:

use strict;
use warnings;

our($foo) = 0;
BEGIN {
        $foo = 2;
}

our($bar);
BEGIN {
        $bar = 3;
}

print "FOO: <$foo>\n";
print "BAR: <$bar>\n";

结果:

$ perl test.pl
FOO: <0>
BAR: <3>

Perl版本:

$ perl -v

This is perl 5, version 22, subversion 0 (v5.22.0) built for x86_64-linux

1 个答案:

答案 0 :(得分:10)

首先,它不是初始化程序;这是一项普通的旧任务。它在代码执行时发生,而不是在创建变量时发生。

其次,编译块后立即评估BEGIN块。

因此,您所写的内容基本等同于以下内容:

# Compile phase
use strict;
use warnings;    
our $foo;
$foo = 2;
our $bar;
$bar = 3;

# Runtime phase
($foo) = 0;
($bar);
print "FOO: <$foo>\n";
print "BAR: <$bar>\n";

更准确地说,

  1. 编译阶段
    1. 编译use strict;
    2. 执行require strict;
    3. 执行import strict;
    4. 编译use warnings;
    5. 执行require warnings;
    6. 执行import warnings;
    7. 编译our($foo) = 0;。 (仅创建$foo。)
    8. 编译BEGIN块:
      1. 编译$foo = 2;
    9. 执行BEGIN阻止:
      1. 执行$foo = 2;
    10. 编译our($bar);。 (仅创建$bar。)
    11. 编译BEGIN块:
      1. 编译$bar = 3;
    12. 执行BEGIN阻止:
      1. 执行$bar = 3;
    13. 编译print "FOO: <$foo>\n";
    14. 编译print "BAR: <$bar>\n";
  2. 运行阶段
    1. 执行($foo) = 0;
    2. 执行($bar);
    3. 执行print "FOO: <$foo>\n";
    4. 执行print "BAR: <$bar>\n";
  3. 如您所见,

    • 您在1.9.1中将2分配给$foo,然后在2.1中将0分配给$foo
    • 您将3分配给1.12.1中的$bar