Я знаю, что в подпрограмме в Perl очень хорошая идея сохранить «переменную по умолчанию» $_
с local
, прежде чем что-либо делать с ней, на случай, если вызывающая сторона ее использует, например ::
sub f() {
local $_; # Ensure $_ is restored on dynamic scope exit
while (<$somefile>) { # Clobbers $_, but that's OK -- it will be restored
...
}
}
Теперь часто причина, по которой вы используете $_
, заключается в том, что вы хотите использовать регулярные выражения, что может привести к удобным «магическим» переменным, таким как $1
, $2
и т. Д. I ' Я тоже хотел бы сохранить эти переменные, но я не смог найти способ сделать это.
Все, что говорит Perlvar, это то, что @+
и @-
, от которых $1
и т. Д., Кажется, зависят внутренне, ссылаются на "последние успешные суб-совпадения в текущей активной динамической области". Но даже это, кажется, расходится с моими экспериментами. Опытным путем следующий код печатает «aXaa», как я и надеялся:
$_ = 'a';
/(.)/; # Sets $1 to 'a'
print $1; # Prints 'a'
{
local $_; # Preserve $_
$_ = 'X';
/(.)/; # Sets $1 to 'X'
print $1; # Prints 'X'
}
print $_; # Prints 'a' ('local' restored the earlier value of $_)
print $1; # Prints 'a', suggesting localising $_ does localise $1 etc. too
Но что меня действительно удивляет, так это то, что, по крайней мере, в моем ActivePerl 5.10.0 комментирование строки local
все еще сохраняет $1
- то есть ответ «aXXa» - производится! Похоже, что лексическая (не динамическая) область действия заключенного в фигурные скобки блока каким-то образом сохраняет значение $1
.
Так что я нахожу эту ситуацию в лучшем случае запутывающей и хотела бы услышать окончательное объяснение. Имейте в виду, я бы на самом деле согласился на пуленепробиваемый способ сохранения всех магических переменных, связанных с регулярными выражениями, без необходимости перечислять их все как в:
local @+, @-, $&, $1, $2, $3, $4, ...
что явно отвратительно. До тех пор я буду беспокоиться о том, что любое регулярное выражение, к которому я прикоснусь, сожжет что-то, чего не ожидал вызывающий объект.
Спасибо!