while 循环不循环过去 1

while loop not looping past 1

我正在尝试在 Perl 中使用 while 循环,它从命令行获取一个参数,即要在字符串上打印的问候数。我写了以下内容:

# Basic settings to catch errors
use strict;
use warnings;

# Define subroutine containing the program
sub WhileNumbers {
    
    # read script arguments
    my $numberOfhellos = @ARGV;
    chomp($numberOfhellos);
    
    # Loop through the files
    my $counts = 1;
    while($counts <= $numberOfhellos) {
        # Get user input the protein of interest
        print ("Hello number $counts \n");
        
        $counts ++;
        
    }
    

}

# Calling the subroutine
WhileNumbers();

当我运行: $ perl hellos.pl 3

我得到输出:

Hello number 1

虽然在现实中我想要:

Hello number 1

Hello number 2

Hello number 3

知道为什么 while 循环没有按预期工作吗?

问题在这里:

my $numberOfhellos = @ARGV;

您正在将数组分配给标量变量。这给你的是数组中元素的数量。由于您将单个参数 (3) 传递给您的脚本,即

@ARGV = ("3")

这会将 $numberOfHellos 设置为 1

修复方法是将 $numberOfhellos 设置为 @ARGV 的第一个元素,如:

my $numberOfhellos = $ARGV[0];

或者,

my ($numberOfhellos) = @ARGV;

which (because of the parentheses) 执行列表赋值,它将 @ARGV 的第一个元素存储在 left-hand 侧列表的第一个元素中,即它也结束设置 $numberOfhellos = $ARGV[0].

另外,你不需要这个:

chomp($numberOfhellos);

chomp 用于从 readline 函数返回的字符串中删除结尾的换行符。这里不涉及换行符。


也就是说,在 Perl 中编写计数循环的更惯用的方法是使用 for(和一个范围)而不是 while:

my $numberOfHellos = $ARGV[0];

for my $count (1 .. $numberOfHellos) {
    print "Hello number $count\n";
}

当你做的时候

...
my $numberOfhellos = @ARGV;
...

使用标量上下文,$numberOfhellos 获取分配的 @ARGV 中的元素数,如果传递一个参数,则为 1

将第一个元素显式分配给变量。

...
my $numberOfhellos = $ARGV[0];
...

那里也不需要chomp()。您可能会将 @ARGV<STDIN> 或类似的混淆。但是检查参数是否符合您的预期并没有什么害处。那就是检查他们的号码,如果第一个是整数。类似于:

...
my $numberOfhellos;
if (scalar(@ARGV) == 1
    && $ARGV[0] =~ m/\A[0-9]+\z/) {
    $numberOfhellos = $ARGV[0];
}
else {
    die("Wrong arguments");
}
...

请注意,scalar(@ARGV) 强制 @ARGV 上的标量上下文导致其元素数。 IE。与您最初的作业中发生的情况相同。