2010-03-11 4 views
6

Je l'ai trouvé dans un module de boucle écrit comme ceciQuestion sur la valeur foreach

for(@array) { 
    my $scalar = $_; 
    ... 
    ... 
} 

Y at-il la différence entre ceci et la manière suivante d'écrire une boucle for?

for my $scalar (@array) { 
    ... 
    ... 
} 

Répondre

11

Oui, dans le premier exemple, la boucle for agit comme un topicalizer (réglage $_ qui est l'argument par défaut à de nombreuses fonctions Perl) sur les éléments dans le tableau. Cela a pour effet secondaire de masquer la valeur $_ à l'extérieur de la boucle for. $_ a une portée dynamique et sera visible dans toutes les fonctions appelées depuis la boucle for. Vous devez principalement utiliser cette version de la boucle for lorsque vous envisagez d'utiliser $_ pour ses fonctionnalités spéciales.

De même, dans le premier exemple, $scalar est une copie de la valeur dans le tableau, alors que dans le second exemple, $scalar est un alias à la valeur dans le tableau. Cela est important si vous envisagez de définir la valeur du tableau dans la boucle. Ou, comme le signale utilement le daotoad, le premier formulaire est utile lorsque vous avez besoin d'une copie de l'élément de tableau sur lequel travailler, comme avec les appels de fonctions destructifs (chomp, s///, tr/// ...).

Enfin, le premier exemple sera légèrement plus lent.

+0

Bonne réponse, ++. Cependant, je ne suis pas d'accord que 'for (@array) {}' ne devrait être utilisé que si vous opérez principalement sur '$ _'. Le fait que la première version force une copie est bénéfique si vous envisagez de changer la valeur de '$ scalar'. Il n'y a aucune raison d'écrire 'pour mon $ alias (@array) {my $ scalar = $ alias; ...} '. Ceci dans une utilisation particulièrement valide de la forme de topicalizer de la boucle for. – daotoad

+0

@daotoad => Je suis d'accord, répondre mis à jour, merci d'avoir rattrapé –

3

$_ est l'espace d'entrée et de correspondance de motif par défaut. En d'autres termes, si vous lisez à partir d'un descripteur de fichier en haut d'une boucle while, ou exécutez une boucle foreach sans nommer de variable de boucle, $_ est configuré pour vous.

Cependant, si vous écrivez une boucle foreach et nommez une variable de boucle, $ _ est pas défini up.This peut être justifiée par le code suivant:

1. #!/usr/bin/perl -w 
2. @array = (1,2,3); 
3. foreach my $elmnt (@array) 
4. { 
5. print "$_ "; 
6. } 

La sortie étant « Utilisation de la valeur non initialisée dans concaténation (.) »

Toutefois, si vous remplacez la ligne 3 par:

foreach (@array) 

La sortie est "1 2 3" comme prévu. Maintenant, dans votre cas, il est toujours préférable de nommer une variable de boucle dans une boucle foreach pour rendre le code plus lisible (perl est déjà beaucoup maudit pour être moins lisible), de cette façon, il n'y aura pas non plus besoin de affectation à la variable $_ et aux problèmes de portée qui en résultent.