3

我编写了一个读取文件的简短 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...警告。它为什么抱怨?

4

2 回答 2

8

这在 autodie 的BUGS部分中提到

当 autodie 或 Fatal 与包文件句柄(例如 FILE)一起使用时,可能会生成“仅使用一次”警告。强烈建议使用标量文件句柄


use diagnostics;说:

名称“main::IN”只使用了一次:test.pl 第 9 行 (#1) (W 一次) 可能的错字 印刷错误通常显示为唯一的变量名。如果您有充分的理由拥有一个独特的名称,那么只需以某种方式再次提及它以隐藏消息。我们的声明也是为此目的而提供的。

注意:此警告检测仅使用过一次的包装符号。 这意味着词法变量永远不会触发这个警告。这也意味着所有的包变量 $c、@c、%c 以及 *c、&c、sub c{}、c() 和 c(文件句柄或格式)都被认为是相同的;如果一个程序只使用了一次 $c 并且还使用了其他任何一个,它不会触发这个警告。以下划线开头的符号和使用特殊标识符 (qv perldata) 的符号不受此警告影响。

因此,如果您使用词法文件句柄,那么它不会发出警告。

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";
于 2016-10-10T12:52:54.840 回答
2

我很确定这是因为autodie.

我不知道确切原因,但如果你删除它,它就会消失。

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

错误 ^

当 autodie 或 Fatal 与包文件句柄(例如 FILE)一起使用时,可能会生成“仅使用一次”警告。强烈建议使用标量文件句柄。

我建议这是因为与试图处理它or die相比,它是如何被处理的。autodie

但是我也建议使用 3 参数会更好的风格open

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

要么 autodie要么or die。_ 我必须承认,如果您的过程确实未能通过open.

于 2016-10-10T12:55:00.950 回答