2010-10-28 2 views
4

Je travaille sur le patch de Zoidberg Perl shell pour corriger certaines erreurs que les versions modernes de Perl lancent lors des tests. Remarque, je ne suis pas l'auteur original et je ne le critique pas non plus. Je suis tombé sur un problème intéressant sur lequel j'aimerais avoir un peu d'histoire.

Le code ci-dessous prend un tableau d'entrées et pour chaque sigil de fin de bande et de fin. Ensuite, il stocke ce sigil dans une variable, s'il ne l'a pas trouvé à la place. Le code qui était dans le fichier d'origine ressemblait à un test A et devait avoir fonctionné jusqu'à et y compris perl v5.8 donné cpantesters résultats. Quoi qu'il en soit, le problème est que si le // s ne se trouve pas dans un test "if", lors de la boucle, la variable $ 1 persiste avec la dernière valeur. Voici mes tests. Je me demandais si les gens pouvaient expliquer pourquoi cela se produisait et/ou pourquoi cela fonctionnait, je pense que je comprends ce qui se passe.

#!/usr/bin/perl 

use strict; 
use warnings; 

my @a = qw/n a$ [email protected] 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"; 
} 

Répondre

7

De perlre:

REMARQUE: matchs ayant échoué en Perl ne sont pas remis à zéro les variables de match, ce qui facilite l'écriture de code que tests pour une série de plus spécifiques cas et se souvient du meilleur match.

Mais vous avez raison, le test A a fonctionné comme les deux autres en 5.8.9. Je ne peux rien trouver dans le 5.10.0 release notes qui l'explique, mais il y avait de nombreux changements RE dans 5.10, et l'un d'entre eux doit avoir affecté cela. Je ne pense pas que le comportement 5.8 ait jamais été voulu.

+0

C'est pourquoi, dans la plupart des cas, il faut utiliser 'if (regex) {# use $ 1, etc.'. – musiKk

+0

Merci pour cela, cela n'a pas toujours été le cas, ce comportement a-t-il changé, peut-être avec la version 5.10? Je suis nouveau à la scène Perl, ~ 1 an. –

+0

'Je ne pense pas que le comportement 5.8 ait jamais été voulu. 'Ouais, je pense que c'est ce que je me demandais. Merci! –

Questions connexes