Perl : 名称 "main::IN" 只用了一次,但实际用过

Perl : Name "main::IN" used only once, but it is actually used

我正在编写一个读取文件的简短 perl 脚本。见 tmp.txt:

1   gene_id "XLOC_000001";  gene_name "DDX11L1";    oId
1   gene_id "XLOC_000001";  gene_name "DDX11L1";    oId
1   gene_id "XLOC_000001";  gene_name "DDX11L1";    oId
1   gene_id "XLOC_000001";  gene_name "DDX11L1";    oId

我的 perl 程序,convert.pl 是:

use warnings;
use strict;
use autodie;        # die if io problem with file
my $line;
my ($xloc, $gene, $ens);
open (IN, "tmp.txt")
    or die ("open 'tmp.txt' failed, $!\n");
while ($line = <IN>) {
    ($xloc, $gene) = ($line =~ /gene_id "([^"]+)".*gene_name "([^"]+)"/);
    print("$xloc   $gene\n");
}
close (IN)
    or warn $! ? "ERROR 1" : "ERROR 2";

它输出:

 Name "main::IN" used only once: possible typo at ./convert.pl line 8.
 XLOC_000001   DDX11L1 
 XLOC_000001   DDX11L1 
 XLOC_000001   DDX11L1
 XLOC_000001   DDX11L1 

我用的是IN,所以不明白Name "main::IN" used...警告。为什么会抱怨?

这在 autodie

BUGS 部分中提到

"Used only once" warnings can be generated when autodie or Fatal is used with package filehandles (eg, FILE). Scalar filehandles are strongly recommended instead.


use diagnostics; 说:

Name "main::IN" used only once: possible typo at test.pl line 9 (#1) (W once) Typographical errors often show up as unique variable names. If you had a good reason for having a unique name, then just mention it again somehow to suppress the message. The our declaration is also provided for this purpose.

NOTE: This warning detects package symbols that have been used only once. This means lexical variables will never trigger this warning. It also means that all of the package variables $c, @c, %c, as well as *c, &c, sub c{}, c(), and c (the filehandle or format) are considered the same; if a program uses $c only once but also uses any of the others it will not trigger this warning. Symbols beginning with an underscore and symbols using special identifiers (q.v. perldata) are exempt from this warning.

所以如果你使用词法文件句柄那么它不会警告。

use warnings;
use strict;
use autodie;        # die if io problem with file
use diagnostics;
my $line;
my ($xloc, $gene, $ens);
open (my $in, "<", "tmp.txt")
    or die ("open 'tmp.txt' failed, $!\n");
while ($line = <$in>) {
    ($xloc, $gene) = ($line =~ /gene_id "([^"]+)".*gene_name "([^"]+)"/);
    print("$xloc   $gene\n");
}
close ($in)
    or warn $! ? "ERROR 1" : "ERROR 2";

我很确定这是因为 autodie

我不知道为什么,但是如果你删除它,它就会消失。

如果您阅读 perldoc autodie,您会看到:

BUGS ^

"Used only once" warnings can be generated when autodie or Fatal is used with package filehandles (eg, FILE). Scalar filehandles are strongly recommended instead.

我认为这是因为 or die 的处理方式与 autodie 试图处理它的方式不同。

但是我也建议使用 3 个参数会更好 open:

open ( my $input, '<', 'tmp.txt'); 

autodieor die。我必须承认,如果您的过程确实失败了 open.

,我真的不确定将采用哪种方式解决这两个问题