2010-04-29 5 views
8

J'ai trouvé ceci dans Mail::IMAPClient. D'où vient le $_ en $SEARCH_KEYS{ uc($_) }?D'où vient _ _ dans cette boucle forl foreach?

sub _quote_search { 
    my ($self, @args) = @_; 
    my @ret; 
    foreach my $v (@args) { 
     if (ref($v) eq "SCALAR") { 
      push(@ret, $$v); 
     } 
     elsif (exists $SEARCH_KEYS{ uc($_) }) { 
      push(@ret, $v); 
     } 
     elsif (@args == 1) { 
      push(@ret, $v); # <3.17 compat: caller responsible for quoting 
     } 
     else { 
      push(@ret, $self->Quote($v)); 
     } 
    } 
    return @ret; 
} 
+0

On dirait que cela devrait être $ v. Parfois, ce que vous voyez sont des bugs. :) –

+2

Parce que 8 bugs sur 10 que je trouve à la fin ne sont pas des bugs, je suis un peu prudent. –

+0

Toujours quitte le 2/10 qui sont :) –

Répondre

8

Cela me semble comme une faute de frappe où l'auteur converti un anonyme pour boucle foreach (@args) à un avec un itérateur explicite variables foreach my $v (@args) et a oublié de convertir toutes les incidences de $_-$v.

Vous devriez probablement déposer un bogue sur la distribution sur CPAN.

+2

J'ai écrit un rapport. –

2

Même s'il s'agit probablement d'un bug, voyons comment se comporte ce code.

La valeur de $_ sera déterminée par la portée dynamique actuelle. Qu'est-ce que cela signifie est que $_ aura n'importe quelle valeur (la copie de la portée dynamique de) $_ a dans le sous-programme appelant.

Ainsi, par exemple si je dois:

for (1 .. 5) { 
    foo(); 
    bar(); 
} 

sub foo { 
    print "\$_ = $_\n"; 
} 

sub bar { 

    for ('a' .. 'c') { 
     foo(); 
    } 
} 

Vous obtenez une sortie comme:

$_ = 1 
$_ = a 
$_ = b 
$_ = c 
$_ = 2 
$_ = a 
$_ = b 
$_ = c 
... 

Il est un peu plus étrange en Perl 5.10 et plus, où un $_ lexical existe.

for (1 .. 5) { 
    foo(); 
    bar(); 
} 

sub foo { 
    print "\$_ = $_\n"; 
} 

sub bar { 
    my $_; 
    for ('a' .. 'c') { 
     foo(); 
    } 
} 

Exécuter ce et obtenez:

$_ = 1 
$_ = 1 
$_ = 1 
$_ = 1 
$_ = 2 
$_ = 2 
$_ = 2 
$_ = 2 

Comme vous pouvez le voir, si ce n'est pas un bug, il est probablement une mauvaise idée.

+0

@daotoad => Avez-vous trouvé de bons usages pour le '$ _' lexical? –

+0

Est-ce que le lexicaliced ​​$ _ garde la valeur? Cela ne fonctionne pas: $ _ = 10; {my $ _; dire; } –

+0

Ok, c'est peut-être le truc, ça garde la valeur. –