2010-02-16 3 views

Répondre

2

Vous obtiendrez un avertissement si vous redéclarer un my, our ou state variable dans la portée actuelle ou de la déclaration. Le premier $i n'est pas réellement une variable lexicale. Vous pouvez le prouver en utilisant Devel::Peek:

use Devel::Peek; 

for my $i (1) { 
    Dump $i; 
} 

SV = IV(0x81178c8) at 0x8100bf8 
REFCNT = 2 
FLAGS = (IOK,READONLY,pIOK) 
IV = 1 

Il n'y a pas PADMY drapeau dans FLAGS, ce qui indiquerait que $i est une variable lexicale, déclarée avec my.

9

En fait, vous n'obtenez des avertissements que pour les redéfinitions dans la même portée. Ecriture:

use warnings; 
my $i; 
{ 
    my $i; 
    # do something to the inner $i 
} 
# do something to the outer $i 

est parfaitement valide.

Je ne sais pas si les entrailles Perl gèrent cette façon, mais vous pouvez penser à votre boucle for comme étant analysé comme

{ 
    my $i; 
    for $i (...) { ... } 
    # the outer scope-block parens are important! 
};
+0

Votre deuxième exemple est pas du tout la même chose que la première, à cause de la portée différente, ainsi que l'itérateur de boucle étant aliasé aux éléments du tableau (ce qui signifie que si vous changez $ i dans la boucle, vous allez changer votre tableau, ou générer un avertissement si les éléments sont constants). – Ether

+0

ils sont tous les deux dans la même portée du bloc for alors que vos exemples sont tous les deux dans des portées différentes. –

+0

L'aliasing dans le deuxième exemple fonctionne comme prévu, essayez-le vous-même: my @a = (1 .. 3); {my $ i; pour $ i (1 .. 3) {$ i = 'x'; }} imprime "a: @a"; Comme pour être dans le même cadre: comme le montre la question, la déclaration dans l'expression for n'est clairement pas dans la même portée que la déclaration dans le bloc interne. – willert

Questions connexes