Ich weiß, dass es in einer Subroutine in Perl eine sehr gute Idee ist, die "Standardvariable" $_
mit local
beizubehalten, bevor sie etwas damit macht, falls der Aufrufer sie benutzt, zB:
sub f() {
local $_; # Ensure $_ is restored on dynamic scope exit
while (<$somefile>) { # Clobbers $_, but that's OK -- it will be restored
...
}
}
Oft ist der Grund, warum Sie $_
verwenden, ersteres, weil Sie Regexes verwenden wollen, die Ergebnisse in handliche "magische" Variablen wie $1
, $2
usw. bringen können. Ich möchte diese Variablen auch beibehalten, aber ich habe es nicht getan war in der Lage, einen Weg zu finden, dies zu tun.
Alles was perlvar sagt ist, dass @+
und @-
, von denen $1
usw. abhängen, intern zu sein scheinen, beziehen sich auf die "letzten erfolgreichen Unterübereinstimmungen im aktuell aktiven dynamischen Bereich". Aber selbst das scheint meinen Experimenten zu widersprechen. Empirisch druckt der folgende Code "aXaa", wie ich es mir erhofft hatte:
$_ = '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
Aber was ich wirklich überraschend finde, ist, dass in meiner ActivePerl 5.10.0 zumindest die local
-Zeile immer noch mit $1
kommentiert - - das heißt, die Antwort "aXXa" wird produziert! Es scheint, dass der lexikalische (nicht dynamische) Umfang des geschweiften Blocks den Wert von $1
irgendwie erhält.
So finde ich diese Situation bestenfalls verwirrend und würde gerne eine definitive Erklärung hören. Wohlgemerkt, ich würde mich mit einem kugelsicheren Weg begnügen, alle Regex-bezogenen magischen Variablen zu erhalten, ohne sie alle wie folgt aufzählen zu müssen:
local @+, @-, $&, $1, $2, $3, $4, ...
was eindeutig ein ekelhafter Hack ist. Bis dahin werde ich mir Sorgen machen, dass jeder Regex, den ich berühre, etwas durchkreuzt, was der Anrufer nicht erwartet hat.
Danke!
@pilcrow: ich nicht Ihre Antwort fangen habe aber sah sie schickte mich in einer Zusammenfassung E-Mail-SO - I schätze du hast es gelöscht? Wie auch immer, ich dachte, es wäre eine nützliche Antwort, und wenn Sie das zufällig lesen: Ich suchte nach der ersten Art von Konservierung. Die zweite war tatsächlich, was ich gehofft hatte, würde * nicht * passieren - das würde auf Dinge hinauslaufen, die "lokal" in andere Bereiche "überbluten" sollten, und ja, wenn ich diese Art von "Erhaltung" wollte, würde ich einfach kopieren $ 1 usw. in andere lokale Variablen, wie Sie vorgeschlagen haben. –