mocnii has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I have a script that splits fasta file into number of chunks.
SYNOPSIS
perl fasta_split.pl --in=input_file --chnb=number_of_chunks --chnm=chunk_name
It works in almost all situations: with options, with extra options (you get help), with --help (you get synopsis, options and arguments), with --man (you get entire pod), with --versions (version of the Perl, program, etc.), except one: I can't get it to work when I start it without arguments or options. For instance:
perl fasta_split.pl
should give usage, but all I get is errors. I used Getopt::Long with Pod::Usage. The part with the
GetOptions(...) or pod2usage(-verbose => 1) && exit;
should print usage without any arguments but it does not.
Could you help me to figure out what I did wrong here?
Here is the full script (error message in pod BUGS section):

#!/usr/bin/env perl #it splits fasta file (>prot_id\naaseq\n) into smaller chunks use strict; use warnings; use Getopt::Long; use Pod::Usage; #Usage part my $fasta_split_VER = '0.01'; my ($opt_help, $opt_man, $opt_versions, $opt_name, $outfile, $infile, $number_of_chunks, $chunk_name); GetOptions ( 'help' => \$opt_help, 'man' => \$opt_man, 'versions' => \$opt_versions, 'name' => \$opt_name, 'in=s' => \$infile, 'chnb=i' => \$number_of_chunks, 'chnm=s' => \$chunk_name, ) or pod2usage(-verbose => 1) && exit; pod2usage(-verbose => 1) && exit if defined $opt_help; pod2usage(-verbose => 2) && exit if defined $opt_man; pod2usage(-verbose => 99, -sections => [qw(NAME SYNOPSIS)]) && exit if + defined $opt_name; if(defined $opt_versions){ print "\nModules, Perl, OS, Program info:\n", " Pod::Usage $Pod::Usage::VERSION\n", " Getopt::Long $Getopt::Long::VERSION\n", " strict $strict::VERSION\n", " Perl $]\n", " OS $^O\n", " fasta_split.pl $fasta_split_VER\n", " $0\n", "\n\n" and exit; } #end Usage part #define number of chunks and chunk name open(my $instream, "<", $infile) or die ("error opening input file $in +file: $!"); ... } #end second part exit; =head1 NAME fasta_split.pl =head1 SYNOPSIS perl fasta_split.pl --in=input_file --chnb=number_of_chunks --chnm=ch +unk_name =head1 DESCRIPTION Split fasta file into number of chunks. Chunks get short name + numbe +r. You need to provide input file, number of chunks and chunk name. For help write: perl fasta_split.pl --help perl fasta_split.pl --man =head1 ARGUMENTS --help print Options and Arguments instead of splitting fasta --man print complete man page instead of splitting fasta =head1 OPTIONS --versions print Modules, Perl, OS, Program info --name print name of the script and synopsis --in=input name of the input file --chnb=50 number of chunks needed --chnm=hx name of the chunks =head1 TESTED Modules, Perl, OS, Program info: Pod::Usage 1.51 Getopt::Long 2.39 strict 1.07 Perl 5.016001 OS MSWin32 fasta_split.pl 0.01 =head1 BUGS F:\luka_blast\in>perl fasta_split17.pl Use of uninitialized value $infile in open at fasta_split17.pl line 4 +6. Use of uninitialized value $infile in concatenation (.) or string at +fasta_split17.pl line 46. error opening input file : No such file or directory at fasta_split17 +.pl line 46. =head1 TODO I have no idea. =head1 UPDATES 12.02.2014. Initial working code =head1 EXAMPLE F:\luka_blast\in>perl fasta_split17.pl --in=hu_ex_cl.txt --chnm=jura +--chnb=50 Num of seq: 22106 Num of chunks: 50 Num of seq in chunk: 442 Num of seq left without chunk: 6 File: jura1 ... File: jura50 Last file appended:jura50 =cut

Replies are listed 'Best First'.
Re: Problem with Getopt::Long and Pod::Usage
by toolic (Bishop) on Feb 12, 2014 at 16:11 UTC
    By default, Getopt::Long does not check if you didn't specify an option. From the POD:
    Options are not necessary for the program to work, hence the name 'option'

    Since you require the input file --in option, you need a check to see if the user specified it:

    pod2usage(-verbose => 1) unless defined $infile;

    Another possibility is to provide a default value for $infile in your code.

      Yes thank you this works.
Re: Problem with Getopt::Long and Pod::Usage
by runrig (Abbot) on Feb 12, 2014 at 16:38 UTC
    pod2usage(...) exits all by itself. You don't need all the '&& exit' clauses. And in your example, you didn't need to include any code that didn't include pod2usage(). The rest is noise that makes it harder to see your issue (and makes me less likely to look for the issue). Include the smallest amount of code that demonstrates your problem. This could even be just a GetOptions() call that only has one or two options.