开发者

Perl match outside "if" doesn't reset $1 on loop

I am working on patching the Zoidberg Perl shell to fix some errors that modern Perl versions throw when testing. Note, I am not the original author nor am I criticizing him. I came upon an interesting problem that I would like a little history on.

The code below takes an array of inputs and for each strips off and ending sigil. Then it stores that sigil in a variable, if it didn't find it store 0 instead. The code that was in the original file looked like test A and must have worked until and including perl v5.8 given cpantesters results. Anyway the problem is that if the s/// isn't inside an of an "if" test, upon looping the $1 variable persists with the last value. Here are my tests. I was wondering if people could explain why this happens and or/why it used to work, I think I understand what is happening.

#!/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 "\nTes开发者_JAVA百科t 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";
}


From perlre:

NOTE: Failed matches in Perl do not reset the match variables, which makes it easier to write code that tests for a series of more specific cases and remembers the best match.

But you're right, Test A did work like the other two in 5.8.9. I can't find anything in the 5.10.0 release notes that explains it, but there were numerous RE changes in 5.10, and one of them must have affected this. I don't think the 5.8 behavior was ever intended.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜