4

我正在寻找一种方法来清除 Perl 程序中的所有数组。

目前,我正在调用一个显式“重置”所有数组的子程序:

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

这迫使我找到程序中的所有数组并在子例程中逐字引用它们。

我查看了 perldoc for reset, undef,delete但无法以清除所有数组的方式解释它们中的任何一个。

有没有 Perl 的内置函数可以做到这一点?

如果没有,是否有一个函数可以返回所有数组变量的数组?

前任:

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

哪里getarrays()可能是一个内置的 Perl 函数,它返回程序中任何/所有初始化的数组。


编辑:
我的特殊情况只涉及两个需要重置的全局数组。我出于好奇而不是必要性扩大了这个问题。基本上,我的全局变量是@email_subject& @email_msg

随着脚本的进展和数据的收集/分析,它们的值被推送到其中。在脚本结束时,将发送电子邮件消息,并且脚本可能会根据循环条件变量再次运行。

如果它再次运行,我需要清除这 2 个全局变量,以便它们可以在下一个循环周期中再次聚合。通过字面引用清除这两个数组并没有杀死我,但我只是想知道 Perl 是否已经有一些内置函数来清除数组而不用字面引用它们。

这可能不是完成此任务的最佳方式,但这是我考虑的第一个直观选项。

4

3 回答 3

19

不要使用全局数组。就这么简单。词法数组仅限于声明它们的范围,并在您进入范围时自动开始为空。

如果您必须使用全局变量,无论如何在一个地方跟踪它们都是一个好主意,因此清除它们应该不难。

有人曾经发布了一个现在臭名昭著的工具来让 perlmonks 做你想做的事。在收到对整个想法的大量批评后,该代码被撤回;你可以在这里阅读一些批评:http ://www.perlmonks.org/index.pl?node_id=349496

于 2011-05-17T19:53:54.783 回答
8

你想要这个的事实对我来说是“糟糕的设计”。但是,假设您确切知道您在用这个放射性电锯做什么,您可以通过访问全局符号表哈希%::%main::. (冒号是名称的一部分。)此散列包含从每个已定义的全局符号到对其变量的引用的映射。

像这样的东西就足够了:

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

编辑以删除对数组引用的检查。所有值实际上都是 typeglob 引用,因此无需检查。

于 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
}

所讨论的阵列的效果是相同的,但它不会冒破坏任何您不打算破坏的风险。您甚至可以使用my而不是our与第二个示例一起使用,而第一个示例要求变量位于符号表中(又名用 定义our)。

于 2011-05-17T20:57:55.593 回答