【问题标题】:Perl: store multi-valued cmd line argument directly into hash keysPerl:将多值命令行参数直接存储到哈希键中
【发布时间】:2016-02-04 02:03:12
【问题描述】:

我正在向 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 的各种键作为布尔值来启用/禁用代码的各个部分。我觉得很简单。

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

我希望它们中的每一个也都成为一个哈希键,这样引用它们仍然会快速且容易,就像我稍后在我的代码中所做的那样。

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

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

但是在尝试之后,我发现它只是为 optsuppress 键提供了最后处理的值的值(例如,如果您传入“E F”,则为“F”),而不是为每个值创建键并给它们一个值 1。

谢谢。

【问题讨论】:

    标签: perl hash getopt-long


    【解决方案1】:

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

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

    '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( exists $opt{suppress}{E} ),而不是if( $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,可能会做你想做的事。

    【讨论】:

    • 谢谢!我选择了第一个选项。在阅读了更多内容之后,我发现这比我想做的更常见。此外,我的程序将没有 -- 开关的目录路径作为其主要(非可选)参数来表示它,如果在 --suppress 切换我的操作方式之后立即给出,我的方法就会崩溃。该路径作为抑制哈希键被拾取。
    猜你喜欢
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 2010-09-16
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多