在较新的Getopt :: Long中如何设置默认的可选值

时间:2016-06-01 21:35:43

标签: perl getopt-long

在Perl的Getopt :: Long版本2.39我可以使用

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

表示如果我使用-c,则在%opts给出codon-view时,-c下的-c默认值为20,但没有显式值。另一方面,未提供--codon-view%opts,则哈希表中的值不会存储在$ 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] 中。

在2.48中,这不再有效,我在Getopt::Long's documentation

中看不到
main.c

我如何实现旧行为?

帮助!

4 个答案:

答案 0 :(得分:5)

这是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]

我不确定,但我认为这是无意中完成的,所以我提交了bug report

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

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

您在使用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控制是否允许--opt=以及它应该做什么。如果没有gnu_compat,则--opt=会出错。使用gnu_compat--opt=会提供选项opt和空值。这是GNU getopt_long()的方式。

因此,如果您--codon-view=将{0}分配给$opts{"codon-view"},则只需使用

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

而不是

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

答案 1 :(得分:3)

GetOptions()来电之前设置默认值。如果命令行中未提供该选项,则不会覆盖默认值。

$ 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

Getopt::Long文档中有a trivial example

答案 2 :(得分:1)

这是另一个可能但不太好的解决方案:包括Getopt :: Long.pm的副本,它只有一个文件,但我已经将包名称空间更改为不同的名称,例如MyPackage的:: GetoptLong。

这不是一个理想的答案,但如果你需要一些东西来保持兼容性并且没有更好的ikegami解决方案,那就要记住了。

答案 3 :(得分:0)

我喜欢将我的选择分配给哈希..

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'} );
}

现在,如果用户在没有参数的情况下运行./you-app -c,则会创建$opt{c}密钥,但其值为undef,因此您需要检查是否已使用{{1}触发该密钥}。

仅当左侧为exists(通常为||=)时,falsey运算符才会将右侧指定为左侧。需要注意的是,如果有人undef,它将分配默认值......但我会继续并认为-c 0可能是你旗帜的不良论据。