使用perl @ARGV

use*_*923 1 perl argv

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

    foreach (@ARGV)
            {
                pop @ARGV;
            }
Run Code Online (Sandbox Code Playgroud)

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

dus*_*uff 5

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

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

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

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

@ARGV = ();
Run Code Online (Sandbox Code Playgroud)


Ste*_*ker 5

你的错误:你正在使用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;
Run Code Online (Sandbox Code Playgroud)

测试运行:

$ 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
Run Code Online (Sandbox Code Playgroud)

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

while (@ARGV) {
    ++$count;
    print "ARGV beginning loop ${count}: ", scalar(@ARGV), "\n";
    pop @ARGV;
    print "ARGV end loop ${count}: ", scalar(@ARGV), "\n";
}
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)

也就是说:帮自己一个忙,重新考虑您的软件架构/设计。为自己的目的滥用具有定义语义的 Perl 变量是一个非常糟糕的主意。

  • 答案是给以后读到这篇文章的每个人的,而不仅仅是问这个问题的人。 (3认同)
  • 这与 Perl 无关 - 对于在 *any* SW 开发环境中滥用功能,我会给出相同的答案。“我做/使用 X,因为我可以/它对我有用”是糟糕的软件开发实践,您的问题举例说明了它可能导致什么问题。 (2认同)