当静态范围内没有任何变量时,我在perl中的表现如何?

问题描述 投票:0回答:2

这里是第一个例子:

$g=5;
sub A {
    my  $x=2;    # $x uses static scoping
    local $y=3;  # $y uses dynamic soping
    local $g=7;
    print "In A: g=$g, x=$x, y=$y\n";
    B();
}

sub B {
    print "In B: g=$g, x=$x, y=$y\n";
    C();
}

sub C {
    print "In B: g=$g, x=$x, y=$y\n";
}

A();
print "In main: g=$g, x=$x, y=$y\n";

这是第一个示例的输出:

In A: g=7, x=2, y=3
In B: g=7, x=, y=3
In B: g=7, x=, y=3
In main: g=5, x=, y=

这里是第二个例子:

sub big {
    my $var=1;
    sub sub1 () {
    print "  In sub1 var=$var\n";
    }
    sub sub2 () {
        $var = 2;
    print "In sub2, var is $var\n";
        sub1();
    }
    sub1();
    sub2();
    sub1();
}

big();

这是第二个输出:

  In sub1 var=1
In sub2, var is 2
  In sub1 var=2
  In sub1 var=2

问题是:为什么在第二个示例中sub Bsub C可以访问my $x=2;,而在第一个示例中sub1()sub2()无法访问my $var=1;,我相信my用于静态作用域在示例2的$x静态范围内没有任何其他sub big,我希望在第二个示例中没有输出,像这样:In sub1 var=。在第二个示例中,sub1sub2如何访问到$x都已经用词my声明了,为什么它的行为不像第一个示例?

perl reference scoping lifetime-scoping
2个回答
1
投票

所有词法变量(用my声明的一个)仅在其最内层的代码块内可见。代码块是由{ ... }包围的语句列表或代码文件。

在您的第一个示例中,所有子例程都在文件的顶级定义。定义子例程的代码块是完全独立的,并且在那些子例程中声明的任何词法变量在其他任何子例程中都不可见。

在第二个示例中,您在子例程sub1()中定义了子例程sub2()big()。这意味着定义两个内部子例程的代码块在定义外部子例程的代码块内-因此,两个内部子例程可以看到在big()中声明的任何词法变量(因为这些变量在任何地方都可见)在big()的代码块中)。


0
投票

不要将命名的subs放置在命名的subs中。

首先,它不会使它们成为私有。

$ perl -e'
   use strict;
   use warnings;

   sub outer {
      sub inner { print "inner\n"; }
   }

   inner();
'
inner

更重要的是,它将导致许多奇怪的行为。

$ perl -e'
   use strict;
   use warnings;

   sub outer {
      my ($x) = @_;
      sub inner { print "inner $x\n"; }
      inner();
   }

   outer(123);
   outer(456);
'
Variable "$x" will not stay shared at -e line 7.
inner 123
inner 123

命名子例程在编译时捕获,因此inner捕获在编译时退出的$x。当outer退出时,其$x被新的$x替换,从而中断outer$xinner的连接。

总是使用use strict; use warnings;

© www.soinside.com 2019 - 2024. All rights reserved.