Perl:将多值命令行参数直接存储到哈希键中

Perl: store multi-valued cmd line argument directly into hash keys

我正在将一些命令行解析添加到 Perl 脚本中,并且我正在尝试弄清楚如何将单个命令行参数的多个值存储为散列键。

下面的 MWE 希望能达到我想做的事情。

# foo.pl    
use Data::Dumper;

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

my %opt=();

my @tempSuppress;

GetOptions ('verbose' => $opt{verbose},
            'suppress:s{1,}' => \@tempSuppress,
            );

print "@tempSuppress\n";


my $tempvar = shift @tempSuppress;
$opt{suppress}{$tempvar}=1;
$tempvar = shift @tempSuppress;
$opt{suppress}{$tempvar}=1;
# Yes, the above 4 lines could be in a loop

warn Dumper(%opt);

if($opt{verbose}){
    print "Some verbose output\n";
}

if(!$opt{suppress}{E}){
    print "Some default output you can suppress with option suppress value 'E'\n";
}

if(!$opt{suppress}{F}){
    print "Some other default output you can suppress with option suppress value 'F'\n"
}

正如您从我的演示打印语句中看到的那样,我希望能够将 %opt 的各种键用作 enable/disable 代码各个部分的布尔值。我认为非常简单。

还有几种不同类型的输出通常会默认打开,但我想要抑制它的选项。我有参数 suppress 可以采用多个值来表示要抑制的类型,例如你可能 运行 foo.pl --suppress E F.

我希望它们中的每一个都成为散列键,这样仍然可以快速轻松地引用它们,就像我稍后在代码中所做的那样。

阅读 options with multiple values 的文档后,我了解了如何将这两个值存储到数组中,正如您在我的代码中看到的那样,我可以将它们复制到 [= 的子键中15=] 输入 opt。我希望将它们放入这些子键的过程可以集成到对 GetOptions 的调用中,例如类似于以下内容:

GetOptions ('verbose' => $opt{verbose},
            'suppress:s{1,}' => $opt{suppress},
            );

但在尝试之后,我看到它只是给 optsuppress 键提供最后处理的值的值(例如 'F' 如果你传入 "E F"), 而不是为每个值创建键并赋予它们值 1。

谢谢。

有几种方法可以做到这一点。

首先使用 Getopt::Long's built in hash options 但要使其成为 require 需要更改您处理选项的方式。说一个值是一个散列,你添加一个 %.

'suppress:s%' => $opt{suppress}

但是 Getopt::Long 期望通过 --suppress 的多次使用传入多个值。这是多少程序执行多参数处理。

program --suppress E --suppress F

如果您尝试 --suppress E F,它将读取为 --suppress E 并在 @ARGV 上保留 F

此外,% 通常与 --option key=value 一起使用。在你的情况下 $opt{suppress}{E} 将没有价值。而不是 if( $opt{suppress}{E} ) 你必须检查 if( exists $opt{suppress}{E} ).


第二种选择是使用a user defined function。这具有可重复用于多个选项的优点。

sub listopt_to_hash {
    my($name, $val) = @_;
    $opt{$name}{$val} = 1;
    return;
}

GetOptions(
    'verbose' => $opt{verbose},
    'suppress:s{1,}' => \&listopt_to_hash
);

最后的选择是使用不同的模块。有 many, many, many Getopt modules on CPAN,其中一个可能会满足您的要求。