rocky
rocky

Reputation: 7098

In newer Getopt::Long How do I set default optional values

In Perl's Getopt::Long version 2.39 I could use

use Getopt::Long qw( :config gnu_getopt );
GetOptions(
   \my %opts, 
   "codon-view|c:20",    # Optional value, default 20
   "consensus|C:50", 
   ...
)

to indicate that if I use -c the default value would be 20 put in %optsunder key codon-view when -c is given but no explicit value for it is there. On the other hand -c or --codon-view is not supplied, then no value in the hash table is stored for in %opts.

In 2.48 this no longer works and I don't see in Getopt::Long's documentation

$ perl -E'
   use Getopt::Long qw( :config gnu_getopt );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.39
20

$ perl -E'
   use Getopt::Long qw( :config gnu_getopt );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.48
[undef]

How can I achieve the old behavior?

Help!

Upvotes: 5

Views: 1496

Answers (4)

rocky
rocky

Reputation: 7098

Here is another possible but less good solution: include a copy of Getopt::Long.pm, It's only one file, but I have changed the package namespace to something different, e.g. MyPackage::GetoptLong.

This is not an ideal answer, but it is something to keep in mind if you need something to keep compatibility and don't have the better ikegami solution.

Upvotes: 1

ikegami
ikegami

Reputation: 385657

This is a change introduced in 2.48.

$ perl -E'
   use Getopt::Long qw( :config gnu_getopt );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.47
20

$ perl -E'
   use Getopt::Long qw( :config gnu_getopt );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.48
[undef]

I'm not sure, but I think it was done unintentionally, so I filed a bug report.


use Getopt::Long qw( :config gnu_getopt );

is short for

use Getopt::Long qw( :config gnu_compat bundling permute no_getopt_compat );

How invested are you in using gnu_compat?

$ perl -E'
   use Getopt::Long qw( :config gnu_getopt );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.48
[undef]

$ perl -E'
   use Getopt::Long qw( :config gnu_compat bundling permute no_getopt_compat );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.48
[undef]

$ perl -E'
   use Getopt::Long qw( :config bundling permute no_getopt_compat );
   say $Getopt::Long::VERSION;
   GetOptions(\my %opts, "codon-view|c:20");
   say $opts{"codon-view"} // "[undef]"
' -- -c
2.48
20

gnu_compat controls whether --opt= is allowed, and what it should do. Without gnu_compat, --opt= gives an error. With gnu_compat, --opt= will give option opt and empty value. This is the way GNU getopt_long() does it.

So if you're ok with --codon-view= assigning zero to $opts{"codon-view"}, simply use

use Getopt::Long qw( :config bundling permute no_getopt_compat );

instead of

use Getopt::Long qw( :config gnu_getopt );

Upvotes: 5

elcaro
elcaro

Reputation: 2297

I like to assign my opts to a hash..

GetOptions(\ my %opt,
    'codon-view|c:i',
);

if ( exists $opt{'codon-view'} ) {
    print "User triggered '-c' flag\n";
    $opt{'codon-view'} ||= 20;
    printf( "codon-view: %d\n", $opt{'codon-view'} );
}

Now if a user runs ./you-app -c with no argument, the $opt{c} key gets created, but it's value is undef, so you much check if it was triggered with exists.

The ||= operator assigns the right-hand side to the left-hand side only if the left-hand side is falsey ( usually undef ). A caveat is that if someone does -c 0 it will assign the default... but I'm going to go ahead and assume 0 is probably a bad argument for your flag.

Upvotes: 1

mob
mob

Reputation: 118605

Set the default value before the GetOptions() call. If the option is not provided on the command line, then the default value will not be overwritten.

$ perl -MGetopt::Long -E '$c=20;GetOptions("c=i"=>\$c); say $c' -- -c 14
14

$ perl -MGetopt::Long -E '$c=20;GetOptions("c=i"=>\$c); say $c' --
20

There is a trivial example in the Getopt::Long documentation.

Upvotes: 3

Related Questions