私は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
などの便利な「魔法の」変数に結果を入れたいからです。これらの変数も保存したいと思いますが、それを行う方法を見つけることができました。すべては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, ...
はっきり嫌なハックです。それまでは、私は正規表現が私に触れると、呼び出し元がclobberedすることを期待していない何かが壊れてしまうのではないかと心配します。
ありがとうございます!
@pilcrow:私はあなたの答えをキャッチしませんでしたが、あなたはそれを削除したと思いますか?とにかく、それは有用な答えだと思っていました。もしあなたがこれを読んでいれば、私は第一の種類の保存を探していました。 2番目は実際には私が望んでいたものではありませんでした。それは、他のスコープにローカルで "出るべき"ものになるでしょう。そう、 "保存" $ 1などを他のローカル変数に追加します。 –