Я работаю над исправлением оболочки Zoidberg Perl, чтобы исправить некоторые ошибки, которые выдают современные версии Perl при тестировании. Обратите внимание, я не являюсь первоначальным автором и не критикую его. Я столкнулся с интересной проблемой, о которой я хотел бы рассказать немного истории.
Приведенный ниже код принимает массив входных данных и для каждого снимает и заканчивает сигил. Затем он сохраняет этот сигил в переменной, если он не нашел, что он хранит 0 вместо этого. Код, который был в исходном файле, выглядел как тест А и должен был работать до и включая perl v5.8 с cpantesters результатами. В любом случае проблема заключается в том, что если s /// не находится внутри критерия «если», то после зацикливания переменная $ 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";
}