Perl変数を異なるスタックフレームにローカライズするにはどうすればよいですか?
質問
コードのさまざまな場所に次のコードを効率的に書き出す自動生成コードがあります:
no warnings 'uninitialized';
local %ENV = %ENV;
local $/ = $/;
local @INC = @INC;
local %INC = %INC;
local コードのさまざまな場所に次のコードを効率的に書き出す自動生成コードがあります:
<*>
コードを自動生成するとき、コードが「美しい」ことは厳密に必要ではないと主張する人もいますが、それをサブルーチンに引き出したいと思います。ただし、そのサブルーチン内のこれらの変数はローカライズされます。呼び出しスタックフレームでこれらの変数をローカライズする方法はありますか?
更新:同様に、より高いスタックフレームでevalを実行できると便利です。 Pythonにはすでにこれがあると思います。 Perlもそうしたらいいと思います。
= コードのさまざまな場所に次のコードを効率的に書き出す自動生成コードがあります:
<*>
コードを自動生成するとき、コードが「美しい」ことは厳密に必要ではないと主張する人もいますが、それをサブルーチンに引き出したいと思います。ただし、そのサブルーチン内のこれらの変数はローカライズされます。呼び出しスタックフレームでこれらの変数をローカライズする方法はありますか?
更新:同様に、より高いスタックフレームでevalを実行できると便利です。 Pythonにはすでにこれがあると思います。 Perlもそうしたらいいと思います。
;
local $| = $|;
local %SIG = %SIG;
use warnings 'uninitialized';
コードを自動生成するとき、コードが「美しい」ことは厳密に必要ではないと主張する人もいますが、それをサブルーチンに引き出したいと思います。ただし、そのサブルーチン内のこれらの変数はローカライズされます。呼び出しスタックフレームでこれらの変数をローカライズする方法はありますか?
更新:同様に、より高いスタックフレームでevalを実行できると便利です。 Pythonにはすでにこれがあると思います。 Perlもそうしたらいいと思います。
解決
おそらく、これらのローカルを使用するコードをクロージャーとして生成するように調整できますか?その後、次のことができます
sub run_with_env {
my ($sub, @args) = @_;
no warnings 'uninitialized';
local %ENV = %ENV;
local $/ = $/;
local @INC = @INC;
local %INC = %INC;
local おそらく、これらのローカルを使用するコードをクロージャーとして生成するように調整できますか?その後、次のことができます
<*> = おそらく、これらのローカルを使用するコードをクロージャーとして生成するように調整できますか?その後、次のことができます
<*>;
local $| = $|;
local %SIG = %SIG;
use warnings 'uninitialized';
$sub->(@args);
}
run_with_env(sub {
# do stuff here
});
run_with_env(sub {
# do different stuff here
});
他のヒント
なぜQuantumPeteがダウン投票されているのかはわかりませんが、彼はこの点について正しいようです。 local
に呼び出しブロック内の変数を初期化するように指示することはできません。その機能は特別であり、それが行う初期化/分解は、それが実行されたブロックでのみ機能します。
Sub :: Uplevel や Devel :: RunBlock を使用すると、&quot;愚か者サブルーチンの caller()
か、より高いスタックフレームへの値の「ロングジャンプリターン」を行いますが、どちらも local
が変数を処理する方法に影響を与えません(試しました:)
したがって、現時点では、必要なスコープでローカル宣言を使用する必要があるようです。
Perlにそれほど詳しくないので、実際に可能であれば許してください。ただし、通常、スタックフレームにローカルな変数は、そのスタックフレーム内でのみ使用できます。上位または下位からアクセスすることはできません(ハックポインター演算を行う場合を除き、成功することは保証されません)。 残念ながら、変数宣言の大きなブロックは、一緒に暮らさなければならないものです。
QuantumPete
perldoc perlgutsのコメント:
The "Alias" module implements localization of the basic types within
the caller's scope. People who are interested in how to localize
things in the containing scope should take a look there too.
FWIW。これがいかに簡単かを確認するのに十分なほどAlias.pmを詳しく見ていない。
TCLでは、アップレベルを使用できます。 Perlについてはわかりません。
Perlには Sub :: Uplevel