使用perl @ARGV

问题描述 投票:1回答:3

在perl应用程序中,我使用@ARGV传递变量。当总有两个变量并且总是相同的两个没有问题。现在它变得更复杂,所以我需要在添加它之前“清空”@ARGV。所以我认为这会奏效:

    foreach (@ARGV)
            {
                pop @ARGV;
            }

它没有。当有四个元素时,它只删除两个元素。知道为什么应该这样吗?或者其他任何排空方式?

perl argv
3个回答
5
投票

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

这是一个糟糕的设计,应该避免。如果需要传递值,请使用函数参数,或至少使用您自己的全局变量。不要(ab)为此使用特殊变量。

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

如果要将数组设为空,请为其指定一个空列表:

@ARGV = ();

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

那就是说:请帮自己一个忙,重新思考你的SW架构/设计。为自己的目的而滥用Perl变量和定义的语义是一个非常糟糕的主意。


1
投票

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

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

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

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

@ARGV = ();

但我不得不说使用@ARGV听起来像是一个糟糕的主意。 @ARGV有一个明确的目的 - 它包含传递给程序的命令行参数。实际上没有必要将它用于其他任何事情。如果你想要自己的数组,那么只需创建一个新数组。

© www.soinside.com 2019 - 2024. All rights reserved.