Perl: имя "main::IN" используется только один раз, но на самом деле используется

Я пишу короткий 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... предупреждение. Почему это жалуется?

2 ответа

Решение

Это упоминается в разделе ошибок в Autodie

При использовании 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";

Я уверен, что это из-за autodie,

Я не знаю точно, почему, но если вы удалите его, он уйдет.

Если вы читаете perldoc autodie вот увидишь:

ОШИБКИ ^

При использовании autodie или Fatal с дескрипторами файлов пакета (например, FILE) могут генерироваться предупреждения "Использовано только один раз". Вместо этого настоятельно рекомендуется использовать скалярные файловые дескрипторы.

Я бы предположил, что это из-за того, как or die обрабатывается, по сравнению с autodie пытаясь справиться с этим.

Тем не менее, я бы также предположил, что было бы гораздо лучше использовать аргумент 3 open:

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

И либо autodie или же or die, Я должен признаться, я не совсем уверен, какой способ будет применен, если ваш процесс потерпел неудачу open,

Другие вопросы по тегам