歴史的背景:
Perlでは、変数のスコープを制限するためにmy(レキシカルスコープ)とlocal(動的一時再割り当て)の演算子を使用できます。localは、グローバル変数や特殊なハンドル($_、$/、$@、%ENVなど)の再定義によく使用されます。
問題:
主な問題は、動的スコープとレキシカルスコープの混乱です。localは新しい変数を作成せず、ブロックの実行中にグローバル(またはパッケージ)変数の値を一時的に置き換えます。このことは、$/(行区切り)、$_(デフォルト変数)、$^W(警告フラグ)、%ENV、STDIN/STDOUTといった変数の再割り当てにおいて特に重要です。
解決策:
コード例:
our $Global = "Hello!"; sub change1 { my $Global = "Bye!"; print "$Global "; } sub change2 { local $Global = "Bye!"; print "$Global "; } print "$Global "; # Hello! change1(); # Bye! print "$Global "; # Hello! change2(); # Bye! print "$Global "; # Hello!
主な特徴:
localは、myで宣言されたレキシカル変数に適用できますか?
いいえ、localはパッケージグローバル変数でのみ機能します。myでのオブジェクトには効果がありません。
特殊なハンドル(例えばSTDIN)にlocalを適用するとどうなりますか?
localを使用して、例えばサブルーチン内で入力/出力ストリームをグローバルに影響を与えずに一時的に再割り当てできます。ブロックを出た後、ハンドルは復元されます。
関数の再帰呼び出しにおけるlocalとmyの重要な違いは何ですか?
localは「push/pop」スタックの値を保証します。各呼び出しは、一時的にパッケージの値を再定義し、入れ子呼び出しはこの再定義された値を取得します。myは、ブロック内で唯一のレキシカル値を提供し、内側には継承されません。
テストではlocalを使用して%ENVを置き換え、ブロックを出た後に思わぬ副作用が他のスレッドで発生します。コードがマルチスレッドであり、localが適切に使用されていないためです。
メリット:
デメリット:
必要なブロックを呼び出す間のみ特殊な変数($/、$@、$SIG)を置き換え、その後の変更を適切に元に戻します。
メリット:
デメリット: