perl闭包和regexp变量

时间:2011-01-27 02:50:00

标签: perl

我在perl的闭包和$1 regexp变量中发现了一个可能的错误。简单地说,他们不会混在一起。

我们来看看这段代码。

use warnings;

while ("1234567890"=~/(.)/sg) {
    push @subs, sub{print $1;};
}

for (@subs) {$_->()}

您可以想象perl现在会打印所有数字 - 相反,我收到了来自未定义$1的10个警告。

它真的是一个错误,还是我错过了perl文档中的某些内容?是否有某些原因,为什么$1未定义且不属于闭包?

2 个答案:

答案 0 :(得分:8)

Perl有两个独立但基本兼容的变量系统。符号表中的全局变量,以及范围绑定词法填充的词法变量。

全局变量可以是符号解除引用的目标,并且受local的动态范围限制。可以关闭词法变量(用my定义)。

正则表达式匹配变量(以及所有Perl的其他特殊变量)是符号表中的全局变量,因此无法关闭它们。

要解决此问题,只需将值复制到词汇:

use warnings;

while ("1234567890"=~/(.)/sg) {
    my $x = $1;                # creates a new lexical that the sub closes over
    push @subs, sub{print $x;};
}

for (@subs) {$_->()}

答案 1 :(得分:7)

我认为答案类似于perl closures and $_的答案。 $1也是一个全局变量。

您需要做的是:

my $x = $1;
push @subs, sub{print $x;};