комбинировать Perl GetoptLong со специальным случаем ARGV?

Я перевожу сценарий оболочки в сценарий Perl, который использует Getopt::Long, и я хочу сохранить совместимость с приведенным ниже случаем, когда, если единственным аргументом сценария является один файл, этот файл используется как файл конфигурации, в то время как обычно нужно получить параметры в GetoptLong.

if [[ $# -eq 1 && -f $1 ]];
then 
    echo "Using config file $1"
    [...]
else 
    if [ $# -lt 2 ]; then usage "INCORRECT NUMBER OF PARAMETERS"; fi
    while getopts ":a:b:c:d:ef" opt;
    do
    [...]

Один из вариантов — сохранить if/else в Perl-скрипте следующим образом:

if (1 == @ARGV && -f $ARGV[0]) {
  # use this config file
  config_file_method($ARGV[0]);
} else {
  # use GetOptions
  GetOptions(
         'a|foo:s' => \$foo,
         'b|bar:s' => \bar,
         [...]
        );
}

Но мне интересно, можно ли этот особый случай включить в функцию GetOptions с некоторой магией:

  GetOptions(
         'if only one element in @ARGV' => 'call config_file_method($ARGV[0])',
         'a|foo:s' => \$foo,
         'b|bar:s' => \bar,
         [...]
        );

Есть идеи?


person 719016    schedule 26.09.2013    source источник
comment
== сравнивает числа. Числа являются скалярами, поэтому == накладывает скалярный контекст на свои аргументы. Каждый экземпляр scalar, который у вас есть, бесполезен.   -  person ikegami    schedule 26.09.2013
comment
@ikegami, заметил, я изменил это.   -  person 719016    schedule 26.09.2013


Ответы (3)


Я не вижу ничего в документации Getopt::Long, которая поддерживает то, что вы ищете для.

Подход, который я бы выбрал, состоит в том, чтобы позволить GetOptions обрабатывать @ARGV. Если что-то все еще находится в @ARGV, вы можете предположить, что это файл конфигурации. Тогда нет необходимости в проверке -f, потому что сабвуфер config_file_method все равно выполнит проверку open/die.

GetOptions(
    'a|foo:s' => \$foo,
    'b|bar:s' => \$bar,
);

config_file_method($ARGV[0]) if @ARGV;
person toolic    schedule 26.09.2013

Я почти уверен, что это невозможно. Если бы вы передавали config_file как параметр вместо аргумента, вы могли бы сделать что-то вроде этого:

GetOptions(
    'c|config_file' => sub { config_file_method($ARGV[0]) if 1 == scalar @ARGV } ,
    'a|foo:s' => \$foo,
    'b|bar:s' => \bar,
    [...]
);
person psxls    schedule 26.09.2013

В Getopt::Long такой опции нет.

И, как вы продемонстрировали, в нем нет абсолютно никакой необходимости. (Это не избавило вас от работы, но добавило сложности, изобретя новый подъязык.)

person ikegami    schedule 26.09.2013