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;
}
The most commonly used special variable is $_, which contains the default input and pattern-searching string. For example, in the following lines − #!/usr/bin/perl foreach ('hickory','dickory','doc') { print $_; print "\n"; }
A foreach loop runs a block of code for each element of a list. No big whoop, “perl foreach” continues to be one of the most popular on Google searches for the language.
A foreach loop is used to iterate over a list and the variable holds the value of the elements of the list one at a time. It is majorly used when we have a set of data in a list and we want to iterate over the elements of the list instead of iterating over its range.
In many programming languages you use the break operator to break out of a loop like this, but in Perl you use the last operator to break out of a loop, like this: last; While using the Perl last operator instead of the usual break operator seems a little unusual, it can make for some readable code, as we'll see next.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With