perl闭包和regexp变量

perl闭包和regexp变量,perl,Perl,我在perl的闭包和$1regexp变量中发现了一个可能的错误。简单地说,它们不会混合在一起 让我们看看这个代码 use warnings; while ("1234567890"=~/(.)/sg) { push @subs, sub{print $1;}; } for (@subs) {$_->()} 您可以想象perl现在将打印所有数字——相反,我收到了来自undefined$1的10条警告 这真的是一个bug,还是我在perl文档中遗漏了什么?有什么原因吗,为什么$1

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

让我们看看这个代码

use warnings;

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

for (@subs) {$_->()}
您可以想象perl现在将打印所有数字——相反,我收到了来自undefined
$1
的10条警告


这真的是一个bug,还是我在perl文档中遗漏了什么?有什么原因吗,为什么
$1
应该是未定义的,而不是闭包的一部分?

我认为答案与对的答案类似<代码>$1也是一个全局变量

您需要做的是:

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

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) {$_->()}

哦,是的,这是有道理的:)但我想你们应该打印$x。谢谢你们的回答。我给Nylon添加了最佳答案,因为他速度更快,分数更少:)我无法选择2个最佳答案匹配变量更奇怪的是,它们的行为像全局变量,除了递归函数外,它们是自动本地化的。