3

I writing a short perl script that reads in a file. See 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

My perl program, convert.pl is :

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";

It outputs:

 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 

I used IN, so I don't understand the Name "main::IN" used... warning. Why is it complaining?

Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
irritable_phd_syndrome
  • 4,631
  • 3
  • 32
  • 60

2 Answers2

8

This is mentioned under BUGS section of autodie

"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; says:

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.

So if you use lexical filehandle then it will not warn.

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";
Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
2

I'm pretty sure this is because of autodie.

I don't know exactly why, but if you remove it, it goes away.

If you read perldoc autodie you'll see:

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.

I'd suggest that's because of how the or die is being handled, compared to autodie trying to handle it.

However I'd also suggest it would be much better style to use a 3 argument open:

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

And either autodie or or die. I must confess, I'm not really sure which way around the two would be applied if your process did fail the open.

Community
  • 1
  • 1
Sobrique
  • 52,974
  • 7
  • 60
  • 101