2016-06-01 3 views
3

В Getopt в Perl :: Длинная версия 2,39 я мог бы использоватьВ новой Getopt :: Long Как установить дополнительные значения по умолчанию

use Getopt::Long qw(:config gnu_getopt); 
GetOptions(
    \my %opts, 
    "codon-view|c:20", # Optional value, default 20 
    "consensus|C:50", 
    ... 
) 

, чтобы указать, что если я использую -c значение по умолчанию будет 20 положить в %opts под ключ codon-view, когда дано -c, но нет явного значения для него. С другой стороны, -c или --codon-view не поставляется, то значение в хэш-таблице не сохраняется в %opts. не

В 2.48 это уже не работает, и я не вижу в Getopt::Long's documentation

$ perl -E' 
    use Getopt::Long qw(:config gnu_getopt); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.39 
20 

$ perl -E' 
    use Getopt::Long qw(:config gnu_getopt); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.48 
[undef] 

Как можно достичь старого поведения?

Помощь!

+0

Вы уверены, что работали в 2.39? Возвращаясь к 2.24 (выпущено в 2000 году), [документация для параметров со значениями] (https://metacpan.org/pod/release/JV/Getopt-Long-2.24/lib/Getopt/Long.pm# Options-with-values) последовательно показывает спецификации опций формы 'tag = s' или' tag: i', а не 'tag: 20'. – ThisSuitIsBlackNot

+0

Я изменил сообщение, чтобы включить это. То, что вы получаете, соответствует моему поведению. Только когда «-c» или «--codon-view» задано без значения, которое изменяется в результате изменений между 2.39 и 2.48. Также есть изменения в FindOption, которые меняются между этими двумя версиями в отношении 'gnu_getopt'. – rocky

+1

@ThisSuitIsBlackNot, Поиск ': number' – ikegami

ответ

5

Это изменение, внесенное в 2.48.

$ perl -E' 
    use Getopt::Long qw(:config gnu_getopt); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.47 
20 

$ perl -E' 
    use Getopt::Long qw(:config gnu_getopt); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.48 
[undef] 

Я не уверен, но я думаю, что это было сделано неумышленно, поэтому я подал bug report.


use Getopt::Long qw(:config gnu_getopt); 

коротка для

use Getopt::Long qw(:config gnu_compat bundling permute no_getopt_compat); 

Как инвестированы вы в использовании gnu_compat?

$ perl -E' 
    use Getopt::Long qw(:config gnu_getopt); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.48 
[undef] 

$ perl -E' 
    use Getopt::Long qw(:config gnu_compat bundling permute no_getopt_compat); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.48 
[undef] 

$ perl -E' 
    use Getopt::Long qw(:config bundling permute no_getopt_compat); 
    say $Getopt::Long::VERSION; 
    GetOptions(\my %opts, "codon-view|c:20"); 
    say $opts{"codon-view"} // "[undef]" 
' -- -c 
2.48 
20 

gnu_compat управляет ли --opt= разрешено, и что он должен делать. Без gnu_compat, --opt= содержит ошибки. С gnu_compat, --opt= предоставит опцию opt и пустое значение. Это делает GNU getopt_long().

Так что, если вы нормально с --codon-view= назначая ноль $opts{"codon-view"}, просто используйте

use Getopt::Long qw(:config bundling permute no_getopt_compat); 

вместо

use Getopt::Long qw(:config gnu_getopt); 
+0

Поскольку это практичность, мне нужно попросить пользователей поэкспериментировать. На данный момент я использовал код 2.39, скопированный в модуль. Учитывая то, что вы говорите, я полагаю, что могу увеличить версию до 2,47 или около того. – rocky

+0

Посмотрите еще раз. Мое решение не повлияет ни на одного из ваших пользователей. Это просто делает '--opt =' прекратить бросать ошибку. – ikegami

+0

Похоже, что документация для 'gnu_compat' неверна. 'perl -MGetopt :: Long =: config, gnu_compat -E'GetOptions (\% opts," foo: 1 ") или умереть; «<$opts{foo}>» «- --foo =' prints' <0> '; удаление 'gnu_compat' prints' <1> '(вместо того, чтобы давать ошибку). – ThisSuitIsBlackNot

3

Задайте значение по умолчанию перед вызовом GetOptions(). Если опция не указана в командной строке, значение по умолчанию не будет перезаписано.

$ perl -MGetopt::Long -E '$c=20;GetOptions("c=i"=>\$c); say $c' -- -c 14 
14 

$ perl -MGetopt::Long -E '$c=20;GetOptions("c=i"=>\$c); say $c' -- 
20 

Существует в документации Getopt::Longa trivial example.

+0

Наверное, я не знал о предыдущем поведении. Если '-c' не задан, тогда этот ключ не находится в хеше. Если он установлен, тогда и только тогда значение для этого ключа имеет значение по умолчанию. Я отредактирую свой вопрос, чтобы отразить это. – rocky

0

Я хотел бы назначить свои Opts на хэш ..

GetOptions(\ my %opt, 
    'codon-view|c:i', 
); 

if (exists $opt{'codon-view'}) { 
    print "User triggered '-c' flag\n"; 
    $opt{'codon-view'} ||= 20; 
    printf("codon-view: %d\n", $opt{'codon-view'}); 
} 

Теперь, если пользователь запускает ./you-app -c без аргументов, ключ $opt{c} получает создан, но это значение undef, так что вы много проверить, если это был запущен с exists.

Оператор ||= присваивает правую сторону левой стороне, только если левая сторона равна falsey (обычно undef). Оговорка в том, что если кто-то делает -c 0, он назначит по умолчанию ... но я собираюсь идти дальше и предположить, что 0, вероятно, является плохим аргументом для вашего флага.

+0

Прошу прощения, я полностью не сообщил о своей ситуации. Во-первых, да, я использую хэш-параметры. Кроме того, я использую 'use Getopt :: Long qw (config gnu_getopt);' Ваш пример работает, когда gnu_getopt не указан в инструкции использования. Однако, когда он указан, ваш пример больше не работает. Кроме того, это немного более громоздко и ставит в двух местах, что такое 'codon-view | c: 20'. Если мы сможем решить проблему, когда указан gnu_getopt, я соглашусь с этим, если не найдено лучшего решения. – rocky

1

Вот еще один возможный, но менее хорошее решение: включать копию Getopt :: Long.pm, это только один файл, но я изменил пространство имен пакетов на что-то другое, например MyPackage :: GetoptLong.

Это не идеальный ответ, но это то, что нужно иметь в виду, если вам нужно что-то, чтобы сохранить совместимость и не иметь лучшего решения ikegami.

Смежные вопросы