开发者

Where does $_ come from in this Perl foreach loop?

开发者 https://www.devze.com 2022-12-28 19:29 出处:网络
I found this in Mail::IMAPClient. Where does the $_ in $SEARCH_KEYS{ uc($_) } come from? sub _quote_search {

I found this in Mail::IMAPClient. Where does the $_ in $SEARCH_KEYS{ uc($_) } come from?

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;
}


That looks to me like a typo where the author converted an anonymous for loop foreach (@args) to one with an explicit iterator variable foreach my $v (@args) and forgot to convert all the incidences of $_ to $v.

You should probably file a bug against the distribution on CPAN.


Even though this is probably a bug, lets consider how this code behaves.

The value of $_ will be determined by the current dynamic scope. What this means is that $_ will have whatever value (the dynamically scoped copy of) $_ has in the calling subroutine.

So for example if I have:

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

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

sub bar {

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

You get output like:

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

It gets a little weirder in Perl 5.10 and up, where a lexical $_ exists.

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

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

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

Run this and get:

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

As you can see, if this isn't a bug, it's probably a bad idea.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号