Используйте Getopt :: Long в Perl для получения многомерных структур данных - PullRequest
2 голосов
/ 26 ноября 2011

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

myScript.pl --filter 'key1 foo bar' --filter 'key2 baz qux'

#!/usr/local/bin/perl5.8.8
use warnings;
use strict;
use Getopt::Long;
use Data::Dumper;

my %filter;

GetOptions("filter=s" => sub { my @args = split(/\s/, $_[1]); $filter{$args[0]}{value1} = $args[1]; $filter{$args[0]}{value2} = $args[2]; });

print Dumper %filter;

Я получаю удовлетворительный вывод:

$VAR1 = 'key2';
$VAR2 = {
          'value1' => 'baz',
          'value2' => 'qux'
        };
$VAR3 = 'key1';
$VAR4 = {
          'value1' => 'foo',
          'value2' => 'bar'
        };

Однако я хотел бы использовать его без кавычек:

myScript.pl --filter key1 foo bar --filter key2 baz qux --other_option ...

key1 и key2 являются здесь ключами хеширования и будут уникальными.

Есть идеи / предложения?

Ответы [ 2 ]

4 голосов
/ 26 ноября 2011

Когда я последний раз проверял (пару лет назад), ни один из модулей 20-30 Getopt , перечисленных в CPAN, не будет обрабатывать строку аргументов, как вы показываете, и большинство аргументов на основе Cкод разбора, о котором я знаю, тоже не справляется.(У меня есть синтаксический анализатор кода C, который обрабатывает его, при условии, что вы знаете, сколько аргументов нужно использовать. Не ясно, требуется ли вам 1 ключ и 2 значения или список значений может быть более переменным, чем этот.)


Возможно, я не выглядел достаточно внимательно.

Getopt :: Long имеет опцию:

Предупреждение: ниже приводится экспериментальная функция.

Опции могут принимать несколько значений одновременно, например

--coordinates 52.2 16.4 --rgbcolor 255 255 149

Это может быть достигнуто путем добавления спецификатора повтора к спецификации опции.Спецификаторы повтора очень похожи на спецификаторы повтора {...}, которые можно использовать с шаблонами регулярных выражений.Например, приведенная выше командная строка будет обрабатываться следующим образом:

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

Пункт назначения для параметра должен быть массивом или ссылкой на массив.

Можно также указать минимальный имаксимальное количество аргументов, которое принимает опция.foo=s{2,4} указывает параметр, который принимает не менее двух и не более 4 аргументов.foo=s{,} указывает одно или несколько значений;foo:s{,} обозначает ноль или более значений параметров.

Это создаст массив с ключом и двумя значениями в нем.Учитывая, что это должно сочетаться с возможностью иметь несколько записей (по одной на --filter), вам все равно может не повезти, но вам следует мучительно тщательно исследовать Getopt::Long.

3 голосов
/ 26 ноября 2011

Вы можете указать обратный вызов для аргументов, не являющихся параметрами, используя имя параметра <> и соответствующим образом скорректировать хэш %filters, например:

GetOptions('filter=s' =>  \&set_filter, '<>' => \&non_option);

Я полагаю, что ваш @ARGV окажется пустым, если вы не используете --.

...