$ _来自这个Perl foreach循环?

时间:2010-04-29 09:49:59

标签: perl

我在Mail::IMAPClient找到了这个。 $_中的$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;
}

2 个答案:

答案 0 :(得分:8)

在我看来,就像一个拼写错误,作者将匿名for循环foreach (@args)转换为具有显式迭代器变量foreach my $v (@args)的错误,并忘记将$_的所有发生率转换为{ {1}}。

您可能应该针对CPAN上的分发提交错误。

答案 1 :(得分:2)

即使这可能是一个错误,让我们考虑一下这段代码的行为。

$_的值将由当前动态范围确定。这意味着$_将具有调用子例程中$_的任何值(动态范围的副本)。

例如,如果我有:

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

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

sub bar {

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

输出如下:

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

它在Perl 5.10及更高版本中有点怪异,其中存在词汇$_

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

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

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

运行此并获取:

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

正如您所看到的,如果这不是一个错误,那可能是一个坏主意。