Как сгруппировать аргументы при использовании Getopt в Perl? - PullRequest
1 голос
/ 12 ноября 2010

Для сценария perl, который я пишу, может быть много (~ 50) опций командной строки. Большинство из них являются необязательными, поэтому для звонка будут доступны только некоторые опции.

Я использую Getopt::Long, но это не позволяет мне использовать GetOptions более одного раза. В результате я должен использовать все параметры командной строки в одном GetOptions вызове.

Есть ли хороший способ сгруппировать опции при использовании GetOptions?

$ cat test.pl
use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

GetOptions ('a=s' => \$a, 'b=s' => \$b);
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

$ perl test.pl -a=AA -b=BB -c=CC -d=DD
Unknown option: c
Unknown option: d
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
a = AA
b = BB
c = 
d = 
$

Ответы [ 4 ]

6 голосов
/ 12 ноября 2010

Лучше всего вместо этого хранить параметры в хэше:

См. Getopt::Long: сохранение значений параметров в хэше :


Иногда, например, когда есть много опций, наличие отдельной переменной для каждой из них может быть громоздким.GetOptions() поддерживает в качестве альтернативного механизма сохранение значений опций в хэше.

Чтобы получить это, в качестве первого аргумента GetOptions() должна быть передана ссылка на хэш.Для каждой опции, указанной в командной строке, значение опции будет сохранено в хэше с именем опции в качестве ключа.Опции, которые в действительности не используются в командной строке, не будут помещены в хеш, другими словами, exists($h{option}) (или defined()) можно использовать для проверки, использовалась ли опция.Недостатком является то, что предупреждения будут выдаваться, если программа работает под строгим использованием и использует $h{option} без тестирования сначала с exists() или defined().

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

Для параметров, которые принимают значения списка или хеш-значения,это необходимо указать, добавив знак @ или% после типа:

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

Чтобы усложнить задачу, хеш может содержать ссылки на фактические места назначения, например:

my $len = 0;
my %h = ('length' => \$len);
GetOptions (\%h, 'length=i');       # will store in $len

Этот пример полностью эквивалентен:

my $len = 0;
GetOptions ('length=i' => \$len);   # will store in $len

Возможна любая смесь.Например, наиболее часто используемые параметры могут храниться в переменных, а все остальные параметры хранятся в хэше:

my $verbose = 0;                    # frequently referred
my $debug = 0;                      # frequently referred
my %h = ('verbose' => \$verbose, 'debug' => \$debug);
GetOptions (\%h, 'verbose', 'debug', 'filter', 'size=i');
if ( $verbose ) { ... }
if ( exists $h{filter} ) { ... option 'filter' was specified ... }
2 голосов
/ 08 июня 2011

Самый прямой ответ - использовать Getopt :: Long :: Configure следующим образом:

use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

Getopt::Long::Configure( qw(pass_through) );
GetOptions ('a=s' => \$a, 'b=s' => \$b);

Getopt::Long::Configure( qw(no_pass_through) );
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

Обратите внимание, что вы должны убедиться, что ваш последний вызов GetOptions должен быть настроен на no_pass_through , чтобы вы получали предупреждения о неизвестных параметрах.

% perl test_getop.pl -a AA -b BB -c CC -d DD -e EE
Unknown option: e
a = AA
b = BB
c = CC
d = DD
1 голос
/ 12 ноября 2010

Что не так с:

GetOptions(
  'a=s' => \$a,
  'b=s' => \$b,
  'c=s' => \$c,
  'd=s' => \$d,
);

Или, если они все короткие, вы можете сделать:и $b для всего, кроме sort сравнений.)

0 голосов
/ 12 ноября 2010

Обычно массивы сводятся в один список перед передачей в функцию, хотя некоторые функции переопределяют это поведение.Используя это, вы можете определить массивы групп опций и передать список массивов в GetOptions.

use strict;
use warnings;
use Getopt::Long;

my ( $opt_a, $opt_b, $opt_c, $opt_d );

my @opt_group_1 = ( 'a=s' => \$opt_a, 'b=s' => \$opt_b );
my @opt_group_2 = ( 'c=s' => \$opt_c, 'd=s' => \$opt_d );
GetOptions( @opt_group_1, @opt_group_2 );

print "a = $opt_a\nb = $opt_b\nc = $opt_c\nd = $opt_d\n";

Вы можете комбинировать это с сохранением значений в хэше, чтобы избежать необходимости создавать огромное количество переменных опций как Zaid.упоминается.

use strict;
use warnings;
use Getopt::Long;

my @opt_group_1 = ( 'a=s', 'b=s' );
my @opt_group_2 = ( 'c=s', 'd=s' );

my %opt;

GetOptions( \%opt, @opt_group_1, @opt_group_2 );

print "a = $opt{a}\nb = $opt{b}\nc = $opt{c}\nd = $opt{d}\n";
...