我有一个奇怪的行为(对于 Python 程序员)子例程,它简化如下:
use strict;
use Data::Dumper;
sub a {
my @x;
sub b { push @x, 1; print "inside: ", Dumper(\@x); }
&b;
print "outside: ", Dumper(\@x);
}
&a;
&a;
我发现结果是:
inside: $VAR1=[ 1 ]
outside: $VAR1 = [ 1 ]
inside: $VAR1=[1, 1]
outside: $VAR1= []
我的想法是调用
&a
时, @x
在“my @x
”之后是空数组,并且在“&b
”之后有一个元素,然后死了。每次我调用 &a
时,都是一样的。所以输出应该都是 $VAR1 = [ 1 ]
。然后我读到类似命名子例程在符号表中定义一次,然后我做“
my $b = sub { ... }; &$b;
”,这对我来说似乎很有意义。如何解释?
最佳答案
根据“perlref”手册页:
named subroutines are created at compile time so their lexical variables [i.e., their 'my' variables] get assigned to the parent lexicals from the first execution of the parent block. If a parent scope is entered a second time, its lexicals are created again, while the nested subs still reference the old ones.
换句话说,一个命名的子程序(你的
b
)有它的 @x
绑定(bind)到父子程序的“第一个”@x
, 所以当 a
第一次调用,b
添加 1
至@x
, 内外副本均指同一个版本。但是,第二次a
被称为,一个新的@x
创建了词法,但是 b
仍然指向旧的,所以它增加了第二个 1
到那个列表并打印它(内部),但是到了 a
的时候为了打印它的版本,它打印出(空的)全新的词汇(外部)。匿名子程序不会出现这个问题,所以当你写
my $b = sub { ... }
,内@x
总是指 a
的“当前”版本的词法@x
.
关于perl - 为什么 "my @variable"在 sub 内并由 sub/sub 修改的行为如此奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41032063/