#perl
#perl
Вопрос:
Я нашел это в Mail::IMAPClient. Откуда берется $_
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;
}
Комментарии:
1. Похоже, что это должно быть $ v. Иногда то, что вы видите, является ошибками. 🙂
2. Поскольку 8 из 10 ошибок, которые я нахожу в конце, не являются ошибками, я немного осторожен.
3. Все еще остаются 2/10, которые являются 🙂
Ответ №1:
На мой взгляд, это похоже на опечатку, когда автор преобразовал анонимный цикл for foreach (@args)
в цикл с явной переменной итератора foreach my $v (@args)
и забыл преобразовать все случаи $_
в $v
.
Вероятно, вам следует сообщить об ошибке в дистрибутиве на CPAN.
Ответ №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
Как вы можете видеть, если это не ошибка, то, вероятно, это плохая идея.
Комментарии:
1. Сохраняет ли лексическое значение $_ значение? Это не работает: $ _ = 10; { my $_; say; }
2. Хорошо, может быть, это foo, который сохраняет значение.
3. @Eric, не совсем, но 99% моей работы должно быть совместимо с Perl 5.8. Это важно учитывать при просмотре опубликованного кода.
4. @sid,
$_
это глобальная переменная, которая получает новую динамическую область видимости (как вы получаете черезlocal
) в каждом цикле for. Таким образом,foo()
просто выводится любое значение, находящееся в том, на что$_
указывает во время его вызова.bar
локализуется$_
, и поэтому теперь оно указывает на другое значение. Взгляните на то, как справиться с областью видимости. Здесь подробно рассказывается о том, как работает динамическое определение области видимости. perl.plover.com/FAQs /…