双while循环挂起的Perl Diamond运算符

时间:2018-11-18 16:19:57

标签: perl while-loop diamond-operator

在我的Perl脚本中,我有一个双重的while循环。我使用菱形运算符从文件中读取行。但是以某种方式,如果我的脚本到达文件的最后一行,它不会返回undef,而是永远挂起。

如果我将代码缩减为一个while循环,则不会发生。所以我想知道我是在做错什么,还是这是已知的语言限制。 (这实际上是我的第一个perl脚本。)

下面是我的脚本。它的目的是计算fasta文件中DNA序列的大小,但是对于其他多行文本文件,可以观察到悬挂行为。

Perl版本5.18.2

从命令行调用,例如perl script.pl file.fa

$l = <>;
while (1) {
    $N = 0;
    while (1) {
        print "Get line";
        $l = <>;
        print "Got line";
        if (not($l)) {
            last;
        }
        if ($l =~ /^>/) {
            last;
        }

        $N += length($l);
    }
    print $N;
    if (not($N)) {
        last;
    }
}

我放置了一些调试打印语句,以便您可以看到最后打印的行是“获取行”,然后挂起。

2 个答案:

答案 0 :(得分:3)

欢迎来到Perl。

您的代码存在的问题是您无法逃避外循环。 <>到达文件末尾时将返回undef。此时,您的内部循环结束,而外部循环将其发送回。强制进一步读取会导致<>开始查看STDIN,而该永不发送EOF,因此您的循环将永远继续。

因为这是您的第一个Perl脚本,所以我将用一些注释为您重写它。 Perl是一种很棒的语言,您可以编写一些很棒的代码,但是主要是由于它的年代久远,因此不再建议使用某些较旧的样式。

use warnings; # Warn about coding errors
use strict; # Enforce good style
use 5.010; # Enable modernish (10 year old) features

# Another option which mostly does the same as above.
# I normally do this, but it does require a non-standard CPAN library
# use Modern::Perl;

# Much better style to have the condition in the while loop
# Much clearer than having an infinite loop with break/last statements
# Also avoid $l as a variable name, it looks too much like $1
my $count = 0; # Note variable declaration, enforced by strict
while(my $line = <>) {
    if ($line =~ /^>/) {
        # End of input block, output and reset
        say $count;
        $count = 0;
    } else {
        $count += length($line);
    }
}

# Have reached the end of the input files
say $count;

答案 1 :(得分:0)

试试“echo | perl script.pl file.fa”。

在我的代码中有相同的“问题”对我有用。

从标准输入获取 EOF。