代码之家  ›  专栏  ›  技术社区  ›  Joel Berger

Perl Match Outside“if”不重置循环中的$1

  •  4
  • Joel Berger  · 技术社区  · 15 年前

    我正致力于修补ZoidbergPerl外壳,以修复现代Perl版本在测试时抛出的一些错误。注意,我不是原作者,也不是在批评他。我遇到了一个有趣的问题,我想了解一下历史。

    下面的代码获取一个输入数组,并为每个条带去掉和结束sigil。然后它将该信号存储在一个变量中,如果没有找到它,则存储0。原始文件中的代码看起来像测试A,必须在给定的Perlv5.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";
    }
    
    1 回复  |  直到 15 年前
        1
  •  7
  •   cjm    15 年前

    perlre :

    注: Perl中失败的匹配不会重置匹配变量,因为 使编写代码更容易 一系列更具体的测试 案例和记忆最佳匹配。

    但你是对的,测试A的效果和5.8.9中的其他两个一样。我在里面找不到任何东西 5.10.0 release notes 这就解释了这一点,但5.10中有许多重新修改,其中一个肯定影响了这一点。我不认为5.8的行为是有意的。