是否有内置函数来清除所有变量值

时间:2011-05-17 19:45:17

标签: arrays perl reset undef

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

目前,我正在调用一个明确“重置”所有数组的子例程:

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

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

我查看了resetundefdelete的perldoc,但无法以清除所有数组的方式解释其中任何一个。

是否有Perl的内置功能可以做到这一点?

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

例如:

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

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

<小时/> 修改:
我的特殊情况只涉及两个需要重置的全局数组。我出于好奇而不是必要而扩大了问题。基本上,我的全局变量是@email_subject&amp; @email_msg

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

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

这可能不是实现这一目标的最佳方式,但这是我考虑的第一个直观选项。

3 个答案:

答案 0 :(得分:19)

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

如果你必须使用全局变量,无论如何都要在一个地方跟踪它们是个好主意,所以清除它们并不困难。

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

答案 1 :(得分:8)

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

这样的事情应该足够了:

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

已编辑以删除对阵列引用的检查。所有的值实际上都是typeglob引用,所以不需要检查。

答案 2 :(得分: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)。