我正在修补Zoidberg Perl shell以修复现代Perl版本在测试时抛出的一些错误。请注意,我不是原作者,也不是我批评他。我遇到了一个有趣的问题,我想要一点历史。
下面的代码采用一系列输入,每个条带关闭和结束sigil。然后它将该sigil存储在一个变量中,如果它没有找到它存储0。原始文件中的代码看起来像测试A,并且必须已经工作,直到并包含perl v5.8给出cpantesters结果。无论如何问题是,如果s ///不在“if”测试中,则在循环时,$ 1变量将持续使用最后一个值。这是我的测试。我想知道人们是否可以解释为什么会发生这种情况和/或为什么它曾经发挥作用,我想我明白发生了什么。
#!/usr/bin/perl
use strict;
use warnings;
my @a = qw/n a$ b@ c/;
my @b = @a;
my @c = @a;
print "Test A -- Doesn't work (c !-> 0)\n";
for (@a) {
s/([\$\@\%])$//;
my $arg = $1 || 0;
print $_ . " -> " . $arg . "\n";
}
print "\nTest B -- Works\n";
for (@b) {
my $arg;
if (s/([\$\@\%])$//) {;
$arg = $1;
}
$arg ||= 0;
print $_ . " -> " . $arg . "\n";
}
print "\nTest C -- Works, more clever\n";
for (@c) {
my $arg = s/([\$\@\%])$// ? $1 : 0;
print $_ . " -> " . $arg . "\n";
}
答案 0 :(得分:7)
来自perlre:
注意: Perl中的匹配失败不会重置匹配变量 这样可以更容易地编写代码 测试一系列更具体的 案件并记住最佳匹配。
但是你是对的,测试A确实像5.8.9中的其他两个一样工作。我找不到解释它的5.10.0 release notes中的任何内容,但5.10中有许多RE更改,其中一个必须影响到这一点。我不认为5.8的行为是有意的。