在散列中添加 Getopt::Long 选项,即使在使用重复说明符时也是如此

Add Getopt::Long options in a hash, even when using a repeat specifier

Perl 的 Getopt::Long allows a developer to add their own options to a script. It's also possible to allow multiple values for an option by the use of a repeat specifier,如在正则表达式中所见。例如:

GetOptions('coordinates=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color);

此外,option values can be stored in a hash,像这样:

my %h = ();
GetOptions(\%h, 'length=i');    # will store in $h{length}

我想做的是,将这两种方法结合起来以我的选项散列结束,即使它们有多个值。

例如,假设我想允许三个选项:生日(三个整数)、parents(一个或两个字符串)、名字(正好一个字符串)。 假设我想将这些值放入散列中。我尝试了以下方法:

use strict;
use warnings;

use Getopt::Long;
use Data::Dumper;

my %h = ();
GetOptions(\%h, 'bday=i{3}', 'parents=s{1,2}', 'name=s{1}');

print Dumper(\%h);

并进行了测试,结果如下:

perl optstest.pl --bday 22 3 1986 --parents john mary --name ellen
$VAR1 = {
    'name' => 'ellen',
    'parents' => 'mary',
    'bday' => 1986
};

只有每个选项的最后一个值实际用于哈希。不过,我想要的是:

$VAR1 = {
    'name' => 'ellen',
    'parents' => ['mary', 'john'],
    'bday' => [22, 3, 1986]
};

如果 'ellen' 在数组中,或者所有内容都在散列中,那也很好。

是否不能将 Getopt::Long 的这两个功能结合起来,即将选项放入散列中并使用重复说明符?

如果你想要一个数组,你需要给它一个数组的引用。

local @ARGV = qw( --x y z );
my %h = ( x => [] );
GetOptions(\%h, 'x=s{2}');
print(Dumper(\%h));

或者你需要指定你想要一个数组。

local @ARGV = qw( --x y z );
GetOptions(\my %h, 'x=s@{2}');
print(Dumper(\%h));

输出:

$VAR1 = {
          'x' => [
                   'y',
                   'z'
                 ]
        };

您 link 文档的 Options with multiple values 部分也说了这个

Warning: What follows is an experimental feature.

早些时候说

GetOptions (\%h, 'colours=s@'); # will push to @{$h{colours}}

所以我猜作者的意图是让它以与重复说明符相同的方式工作,并且您发现了一个错误

我建议您使用作为 Perl 安装一部分的 perlbug 实用程序将其报告给 Perl 5 Porters

use Getopt::Long;
# enable for debugging purposes
# Getopt::Long::Configure("debug");
use Data::Dumper;

my %h = ();
GetOptions(\%h, 'bday=i{3}', 'parents=s@{1,2}', 'name=s@{1}');

print Dumper(\%h);

这是你想要的吗?

$VAR1 = { 
          'bday' => 1986,
          'name' => [ 
                      'ellen'
                    ],
          'parents' => [ 
                         'john',
                         'mary'
                       ]
        };