使用perl @ARGV

时间:2019-02-23 21:10:25

标签: perl argv

在perl应用程序中,我使用@ARGV传递变量。 当总是有两个变量,而总是两个时,就没有问题。 现在,它变得更加复杂,因此我需要在添加之前先“空” @ARGV。所以我认为这会起作用:

    foreach (@ARGV)
            {
                pop @ARGV;
            }

不是。当有四个元素时,它将仅删除两个。 知道为什么会这样吗? 还是其他任何清空方式?

3 个答案:

答案 0 :(得分:5)

  

在perl应用程序中,我使用@ARGV传递变量。

这是一个较差的设计,应避免使用。如果需要传递值,请使用函数参数或至少使用自己的全局变量。请勿为此使用特殊变量。

  

现在它变得更加复杂,因此我需要在添加之前先“清空” @ARGV。

如果要使数组为空,请为其分配一个空列表:

@ARGV = ();

答案 1 :(得分:4)

您的错误:您正在使用foreach(提取列表元素)并修改(pop相同数组!引用perlsyn

  

如果LIST的任何部分是数组,则在循环体中添加或删除元素(例如,使用foreach)将使splice感到非常困惑。 所以不要那样做。

以下说明了代码中正在发生的事情:

#!/usr/bin/perl
use warnings;
use strict;

print "ARGV BEFORE: ", scalar(@ARGV), "\n";

my $count = 0;
foreach my $loop (@ARGV) {
    ++$count;
    print "ARGV beginning loop ${count} for ${loop}: ", scalar(@ARGV), "\n";
    pop @ARGV;
    print "ARGV end loop ${count} for ${loop}: ", scalar(@ARGV), "\n";
}

print "ARGV AFTER: ", scalar(@ARGV), "\n";

exit 0;

试运行:

$ perl dummy.pl 1 2 3 4
ARGV BEFORE: 4
ARGV beginning loop 1 for 1: 4
ARGV end loop 1 for 1: 3
ARGV beginning loop 2 for 2: 3
ARGV end loop 2 for 2: 2
ARGV AFTER: 2

将此与在每次迭代中重新检查列表的正确方法进行比较:

while (@ARGV) {
    ++$count;
    print "ARGV beginning loop ${count}: ", scalar(@ARGV), "\n";
    pop @ARGV;
    print "ARGV end loop ${count}: ", scalar(@ARGV), "\n";
}
$ perl dummy.pl 1 2 3 4
ARGV BEFORE: 4
ARGV beginning loop 1: 4
ARGV end loop 1: 3
ARGV beginning loop 2: 3
ARGV end loop 2: 2
ARGV beginning loop 3: 2
ARGV end loop 3: 1
ARGV beginning loop 4: 1
ARGV end loop 4: 0
ARGV AFTER: 0

那是:帮自己一个忙,然后重新考虑您的软件架构/设计。为自己的目的误用具有定义语义的Perl变量是一个极端坏主意。

答案 2 :(得分:1)

您读过the documentation for pop()吗?它说:

  

弹出并返回数组的最后一个值,将数组缩短一个元素。

所以我不清楚您为什么认为它将清空数组。 Perl有很多文档,但是如果您不阅读它,它就没用了:-)

您可以通过向其分配一个空列表来清除数组,如下所示:

@ARGV = ();

但是我不得不说,使用@ARGV听起来是个糟糕的主意。 @ARGV具有明确的用途-它包含传递给您程序的命令行参数。确实没有必要将其用于其他任何用途。如果您想要自己的阵列,则只需创建一个新阵列即可。