调用两次时子程序给出两个不同的输出

时间:2017-05-19 07:35:06

标签: perl

我已经执行了以下一个简单的嵌套子程序,它的输出让我发疯。

#!/usr/bin/perl 

use strict;
use warnings;

sub outer {

   my $a = "123";

   sub inner {
      print "$a\n";
   }

   inner();

   $a = "456";
}

outer();
outer();

输出到

Variable "$a" will not stay shared at E:\Perl\source\public\sss.pl line 9.
123
456

但这怎么可能?

我在inner值为$a时调用123子例程,但为什么在第二次调用外部时我会456。{/ p>

2 个答案:

答案 0 :(得分:4)

perldoc diagnostics为警告Variable "$a" will not stay shared

提供了非常自我解释的说明
use strict;
use warnings;
use diagnostics;

sub outer {
   my $a = "123";
   sub inner {
      print "$a\n";
   }
   inner();
   $a = "456";
}

outer();
outer();

输出

  

变量" $ a"不会在-e第9行(#1)保持共享

   (W closure) An inner (nested) named subroutine is referencing a
    lexical variable defined in an outer named subroutine.

   When the inner subroutine is called, it will see the value of
    the outer subroutine's variable as it was before and during the *first*
    call to the outer subroutine; in this case, after the first call to the
    outer subroutine is complete, the inner and outer subroutines will no
    longer share a common value for the variable.  In other words, the
    variable will no longer be shared.

   This problem can usually be solved by making the inner subroutine
    anonymous, using the sub {} syntax.  When inner anonymous subs that
    reference variables in outer subroutines are created, they
    are automatically rebound to the current values of such variables.
123
456

答案 1 :(得分:3)

在另一个子例程中声明子例程毫无意义。它就好像它是在顶层声明的那样,并且不能正确地作为闭包

运行

如果启用词法子例程(并禁用相应的"实验"警告)并将inner声明为my sub inner,那么您的代码将像您一样工作预期

#!/usr/bin/perl 

use strict;
use warnings 'all';
use feature 'lexical_subs';
no warnings 'experimental::lexical_subs';

sub outer {

   my $a = "123";

   my sub inner {
      print "$a\n";
   }

   inner();

   $a = "456";
}

outer();
outer();

输出

123
123