我已经执行了以下一个简单的嵌套子程序,它的输出让我发疯。
#!/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>
答案 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