2010-04-29 17 views
8

Ho trovato questo in Mail::IMAPClient. Da dove proviene il $_ in $SEARCH_KEYS{ uc($_) }?

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

Sembra che dovrebbe essere $ v. A volte ciò che vedi sono bug. :) –

+2

Poiché 8 bug su 10 che trovo alla fine non sono bug, sono un po 'cauto. –

+0

Lascia ancora il 2/10 che sono :) –

risposta

8

Questo mi sembra un errore di battitura in cui l'autore convertito un anonimo ciclo for foreach (@args) a uno con un iteratore esplicita variabile foreach my $v (@args) e si è dimenticato di convertire tutte le incidenze di $_-$v.

Probabilmente dovresti presentare un bug contro la distribuzione su CPAN.

+2

Ho scritto un rapporto. –

2

Anche se questo è probabilmente un bug, consideriamo come si comporta questo codice.

Il valore di $_ sarà determinato dall'ambito dinamico corrente. Ciò significa che $_ avrà qualsiasi valore (la copia con estensione dinamica di) $_ ha nella subroutine di chiamata.

Così, per esempio se ho:

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

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

sub bar { 

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

Si ottiene in uscita come:

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

Diventa un po 'strano in Perl 5.10 e fino, in cui un lessicale $_ esiste.

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

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

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

Esegui questo e ottenere:

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

Come si può vedere, se questo non è un bug, è probabilmente una cattiva idea.

+0

@daotoad => hai trovato qualche buon uso per lessicale '$ _'? –

+0

Il lessicaliced ​​$ _ mantiene il valore? Questo non funziona: $ _ = 10; {my $ _; dire; } –

+0

Ok, forse è il foo, che mantiene il valore. –