【问题标题】:Variables declared with our and BEGIN block interactions使用我们和 BEGIN 块交互声明的变量
【发布时间】:2016-05-14 14:33:22
【问题描述】:

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

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

【问题讨论】:

    标签: perl scoping lexical-scope


    【解决方案1】:

    首先,它不是初始化器;这是一个简单的旧任务。它发生在代码执行时,而不是创建变量时。

    其次,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: &lt;$foo&gt;\n";
      14. 编译print "BAR: &lt;$bar&gt;\n";
    2. 运行时阶段
      1. 执行($foo) = 0;
      2. 执行($bar);
      3. 执行print "FOO: &lt;$foo&gt;\n";
      4. 执行print "BAR: &lt;$bar&gt;\n";

    如你所见,

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

    【讨论】:

    • 初始化和简单赋值之间的区别是帮助我理解这一点的关键,而不是仅仅知道它——谢谢。
    • our 有一个初始化器是没有意义的,因为our $foo 为同名的包变量创建了一个词法范围的别名(就像\my $foo = \$PACKAGE::foo; 一样) .也就是说,这也只是my 的任务。 (你为什么首先使用our???)
    • 我需要一个打包范围的变量。
    • 极不可能。几乎可以保证是一个错误(非常糟糕的设计),或者在 my 时使用 our 也同样有效。
    猜你喜欢
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多