私はそれが次のように言うでしょう:
あなたの側のベストプラクティスの違反(常に-ローカル-可能な限り可変スコープを使用$_
し、発生した問題だけのために使用を避けてください)
ベストプラクティスの同じ違反によって引き起こされたAPIのバグと相まって、perldocperlvarによって禁止されているように特別な変数をローカライズしていませんlocal $_
。
perldocに加えて、APIはPerlのベストプラクティスに違反しています(Conwayの本のルールのように):
セクション5.6。句読点変数のローカライズ
句読点変数を変更せざるを得ない場合は、ローカライズしてください。
「ローカリゼーション」で前述した問題は、句読点変数の値を変更しなければならない場合はいつでも発生する可能性があります(多くの場合、I / O操作で)。すべての句読点変数はスコープがグローバルです。これらは、完全に何になるかを明示的に制御します。他のほとんどの言語での暗黙の動作:出力バッファリング、入力行番号、入力および出力行の終わり、配列の索引付けなど。
通常、句読点変数を最初にローカライズせずに変更することは重大なエラーです。ローカライズされていない割り当ては、自分で作成しておらず、単に使用しているモジュールであっても、システムのまったく関係のない部分のコードの動作を変更する可能性があります。
ローカルを使用することは、グローバル変数の値を一時的に変更するための最もクリーンで堅牢な方法です。変数が制御する可能性のある「周囲の動作」の影響を最小限に抑えるために、常に可能な限り最小のスコープで適用する必要があります。
perldoc perlvarの完全なドキュメントもここにあります-Webページで「nasty_break」という単語を検索します(ページ内の直接リンクは見つかりませんでしたが、ページの先頭に近いです)
このドキュメントで説明されているほとんどの特殊変数のデフォルト値を変更するときは、十分に注意する必要があります。ほとんどの場合、これらの変数を変更する前にローカライズする必要があります。ローカライズしないと、変更した特別な変数のデフォルト値に依存する他のモジュールに変更が影響する可能性があるためです。これは、ファイル全体を一度に読み取る正しい方法の1つです。
- $ fh、 "<"、 "foo"を開くか、$!;を死ぬ
- ローカル$/; #ローカライズされたスラップモードを有効にする
- 私の$content=;
- $fhを閉じます。
しかし、次のコードはかなり悪いです:
- $ fh、 "<"、 "foo"を開くか、$!;を死ぬ
- undef $ /; #スラップモードを有効にする
- 私の$content=;
- $fhを閉じます。
他のモジュールは、デフォルトの「ラインモード」でファイルからデータを読み取りたい場合があるため、今提示したコードが実行された場合、同じ内部で実行されている他のコードのグローバル値$/が変更されます。 Perlインタプリタ。
通常、変数がローカライズされている場合、この変更が可能な限り最短のスコープに影響を与えることを確認する必要があります。したがって、すでに短い{}ブロック内にいない限り、自分で作成する必要があります。例えば:
- 私の$content='';
- $ fh、 "<"、 "foo"を開くか、$!;を死ぬ
- {{
- ローカル$/;
- $ content =;
- }
- $fhを閉じます。
独自のコードが壊れてしまう例を次に示します。
- for(1..5){
- nasty_break();
- 印刷"$_";
- }
- sub nasty_break {
- $ _ = 5;
- #$_で何かをする
- }
あなたはおそらくこのコードが印刷されることを期待しています:
- 1 2 3 4 5
しかし、代わりに次のようになります。
- 5 5 5 5 5
なんで?nasty_break()は、最初にローカライズせずに$_を変更するためです。修正はlocal()を追加することです:
- ローカル$_= 5;