4

Perlプログラムですべての配列をクリアする方法を探しています。

現在、すべての配列を明示的に「リセット」するサブルーチンを呼び出しています。

sub clear_arrays{(@array1,@array2,@array3)=((),(),());}

これにより、プログラム内のすべての配列を検索し、サブルーチン内で文字通りそれらを参照する必要があります。

reset、、のperldocを調べましたが、undefすべてdeleteの配列をクリアするような方法でそれらを解釈することはできませんでした。

これを行うことができるPerlの組み込み関数はありますか?

そうでない場合、すべての配列変数の配列を返す関数はありますか?

元:

my @prog_arrays = getarrays();
foreach(@prog_arrays){$_ = ();}

getarrays()プログラム内の初期化された配列の一部またはすべてを返す組み込みのPerl関数は どこにあるのでしょうか。


編集:
私の特定の状況には、リセットする必要がある2つのグローバルアレイのみが含まれます。私は必要性よりも好奇心から質問を広げました。基本的に、私のグローバルは@email_subject@email_msgです。

スクリプトが進行し、データが収集/分析されると、値がプッシュされます。スクリプトの最後に電子メールメッセージが送信され、ループ条件変数に応じてスクリプトが再度実行される場合があります。

再度実行する場合は、これら2つのグローバルをクリアして、次のループサイクル中に再度集約できるようにする必要があります。リテラル参照を介してこれら2つの配列をクリアすることは私を殺すことはありませんが、Perlには、文字通り参照せずに配列をクリアするための組み込み関数がすでにあるかどうか疑問に思っていました。

これはこれを達成するための最良の方法ではないかもしれませんが、私が考えた最初の直感的なオプションでした。

4

3 に答える 3

19

グローバル配列を使用しないでください。それはそれと同じくらい簡単です。レキシカル配列は、宣言されたスコープに限定され、スコープに入ると自動的に空で開始されます。

グローバルを使用する必要がある場合は、それらすべてを 1 か所で追跡することをお勧めします。そのため、グローバルをクリアすることは難しくありません。

誰かが、今では悪名高いツールを perlmonks に投稿して、やりたいことができるようにしたことがあります。このコードは、アイデア全体に対する多くの批判を受けて撤回されました。ここでいくつかの批判を読むことができます: http://www.perlmonks.org/index.pl?node_id=349496

于 2011-05-17T19:53:54.783 に答える
8

あなたがこれを欲しがっているという事実は、私には「デザインが悪い」と叫びます。ただし、この放射性チェーンソーで何をしているのかを正確に知っていると仮定すると、グローバル シンボル テーブル ハッシュ%::または%main::. (コロンは名前の一部です。) このハッシュには、定義されたすべてのグローバル シンボルからその変数への参照へのマッピングが含まれます。

次のようなもので十分です。

for my $ref (values %::) {
    @{$ref} = ();
}

配列参照に対するチェックを削除するように編集されました。実際にはすべての値が型グロブ参照であるため、確認する必要はありません。

于 2011-05-17T19:53:12.307 に答える
6

他の回答で述べたように、あなたの要求は、プログラムの設計に関するより大きな問題を示しています。範囲外のレキシカルを使用するか、すべてのグローバル配列を厳密に管理して、それらをクリアする関数を作成する必要があります。

名前空間内のすべての配列を強打することに固執する場合は、少なくとも注意して、Perl が必要とする可能性のある値を上書きしていないことを確認してください:

for (keys %::) {  # for everything in `package main;`
    if (*{$::{$_}}{ARRAY}) {  # if there is an array in the slot
        # clear it unless it is a "special" array
        @{$::{$_}} = () unless /^(?:INC|ISA|EXPORT|EXPORT_OK|ARGV|_|\W)$/
    }
}

私はそれを次のように書きます:

my @global_arrays = \our (@foo, @bar, @baz);
sub clear_global_arrays {
    @$_ = () for @global_arrays
}

問題の配列に対する効果は同じですが、意図しないものを破壊するリスクはありません。my2 番目の例ではなくを使用することもできますがour、最初の例では変数がシンボル テーブルにある必要があります (別名 で定義されていますour)。

于 2011-05-17T20:57:55.593 に答える