Perl Getopt::Long - 仅对定义的参数使用子参数

Perl Getopt::Long - use subparameter only for defined parameter

我希望 --import 参数有一个 "sub-parameter" 只对这个参数起作用,对其他地方不起作用。示例:

app.pl --import --fresh

输出:命令工作

app.pl --export

输出:命令工作

app.pl --export --fresh

输出:找不到命令

GetOpt::Long可以做到吗?请稍微指导一下。

我认为如果不求助于部分解析,最接近 Getopt::Long 的是:

use strict;
use warnings;
use Data::Dumper;
use Getopt::Long;

GetOptions('export=s%{1,5}'=>\my %export, 'another_option=s'=>\my $ao);

print Dumper({ 'export'=> \%export, 'another_option'=>$ao});

perl t1.pl  --export fresh=1 b=2 c=3 --another_option value

$VAR1 = {
          'export' => {
                        'c' => '3',
                        'b' => '2',
                        'fresh' => '1'
                      },
          'another_option' => 'value'
        };

此处export=s%{1,5}--export fresh=1 b=2 c=3解析为散列%export.
s%{1,5} 期望 1 到 5 key=value

选项确实需要一个参数。但是,该参数不使用 --

GetOptions(
   'help'     => \&help,
   'import:s' => $opt_import,
)
   or usage();

defined($opt_import) && ( $opt_import eq '' || opt_import eq 'fresh' )
   or usage("Invalid value for --import");

@ARGV == 0
   or usage("Incorrect number of arguments");

# Convert into booleans for convenience.
$opt_fresh = defined($opt_import) && $opt_import eq 'fresh';
$opt_import = defined($opt_import);

以上接受以下内容:

app.pl --import fresh
app.pl --import
app.pl

请注意,使用 =s 而不是 :s 将强制提供一个值。


示例助手:

use FIle::Basename qw( basename );

sub usage {
   my $basename = basename([=12=]);
   print("usage: $basename [options]\n");
   print("       $basename --help\n");
   print("\n");
   print("Options:\n");
   print("\n");
   print("   --import [fresh]\n");
   exit(0);
}

sub usage {
   if (@_) {
      chomp( my $msg = shift );
      warn("$msg\n");
   }

   my $basename = basename([=12=]);
   warn("Try '$basename --help' for more information.\n);
   exit(1);
}

我认为此调用的目的(对此处的实施很重要)如下。

需要在 --import 选项下设置一个标志(称为 $fresh),以及与 --import 关联的其他标志。此外,可能有一个独立的选项 --fresh,它设置 $fresh 标志。

同时 Getopt::Long doesn't support nested options this can be achieved using its other facilities. Set --import to take an optional argument with :, and set variables in a sub。如果单词 fresh 作为值提交,则设置相应的 ($fresh) 标志。

use warnings;
use strict;
use feature 'say';

use Getopt::Long;

my ($import, $fresh); 

GetOptions( 
    'import:s' => sub { 
        $import = 1;  
        $fresh  = 1 if $_[1] eq 'fresh';
    },
    'fresh!' => $fresh   # if independent --fresh option is needed
);

say 'import: ', $import // 'not submitted';   #/
say 'fresh:  ', $fresh  // 'not submitted';

sub接收两个参数,选项名称和值,值用于检查是否传递了fresh。目前的代码对可能传递的其他单词没有任何作用,但如果提交了 fresh 以外的任何值,它可以中止(使用用法消息)。

无论出于何种特殊原因需要此调用,都可以在子程序中进行编码。

如果确实提供了单独的 --fresh 选项,那么用户需要小心,因为可能会为 $fresh 提交冲突的值 – 一个 --import 和另一个 --fresh 本身。这可以在代码中检查。

选项 --import 仍然可以作为一个简单的标志单独使用。

有效的调用是

gol.pl --import         # $import is 1
gol.pl --import fresh   # $import is 1, $fresh is 1
gol.pl --fresh          # $fresh is 1

由于 fresh 在 sub 中设置为 --import 的值,因此无法使用任何其他选项进行设置。

这与要求的不同之处在于将 fresh 作为一个单词,没有破折号。