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

Perl 在更新的Getopt::Long中,如何设置默认可选值,perl,getopt-long,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,当-c给定但没有明确的值时,默认值将被放入%opts键密码子视图下。另一方面,如果未提供-c或--cod

在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
,当
-c
给定但没有明确的值时,默认值将被放入
%opts
密码子视图下。另一方面,如果未提供
-c
--codon视图
,则哈希表中没有为in
%opts
存储任何值

在2.48中,这已经不起作用了,我看不到了

我如何才能实现旧的行为


救命啊

在调用
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
文档中有。我喜欢将我的选项分配给哈希

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
,因此您需要检查它是否由
触发


||=
运算符仅当左侧为
错误时才将右侧指定给左侧(通常为
undef
)。需要注意的是,如果有人执行
-c0
,它将指定默认值。。。但是我将继续,并假设
0
对于您的标志来说可能是一个不好的参数。

这是在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]
我不确定,但我认为这是无意的,所以我提交了一份申请


是的缩写

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\u compat
控制是否允许
--opt=
,以及它应该做什么。如果没有
gnu\u compat
--opt=
将给出一个错误。使用
gnu\u compat
--opt=
将给出选项
opt
和空值。这就是GNU getopt_long()的工作方式

因此,如果您对
--codon view=
将零赋值给
$opts{“codon view”}
没问题,只需使用

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

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

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


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

你确定这在2.39有效吗?一直追溯到2.24(2000年发布),始终显示形式为
tag=s
tag:i
,而不是
tag:20
的选项规范。我修改了帖子,将其包括在内。你得到的和我的行为相符。只有当
-c
--codon view
未给出值时,行为才会在2.39和2.48之间变化。此外,在这两个版本之间,FindOption也有一些变化,关于
gnu_getopt
@thisSuiteisBlack,搜索
:number
这是在2.48中引入的变化。我不确定,但我认为这是无意的,所以我提交了一份申请。我想我不清楚以前的行为。如果未给出
-c
,则该键不在散列中。如果已设置,则该键的值将具有默认值。我将编辑我的问题以反映这一点。很抱歉,我没有完整地报告我的情况。首先,是的,我确实使用了选项散列。另外,我使用
使用Getopt::longqw(config gnu_Getopt)在use语句中未指定gnu_getopt时,您的示例确实有效。但是,如果指定了它,那么您的示例将不再有效。此外,它还有点麻烦,它将
密码子视图| c:20
的功能放在了两个地方。如果我们能在指定gnu_getopt时解决这个问题,如果找不到更好的解决方案,我会接受。因为这是一个可用性问题,我需要请用户进行实验。我现在所做的是使用复制到模块中的2.39代码。根据你所说的,我想我可以把版本提高到2.47左右。再看看。我的解决方案不会影响您的任何用户。它只是使
--opt=
停止抛出错误。看起来
gnu\u compat
的文档是错误的<代码>perl-MGetopt::Long=:config,gnu\u compat-E'GetOptions(\%opts,“foo:1”)或die;说“”--foo=
打印
;删除
gnu-compat
将打印
(而不是给出错误)。@thisSuitesBlacknot,它确实会在没有
=
选项的
gnu-compat
情况下死亡。///Getopt::Long的测试套件严重不足。@ikegami刚刚检查过。是的,就像你说的那样。这应该很好。谢谢
use Getopt::Long qw( :config bundling permute no_getopt_compat );
use Getopt::Long qw( :config gnu_getopt );