Книга: Программирование на языке Ruby

14.2.1. Разбор флагов в командной строке

14.2.1. Разбор флагов в командной строке

Для разбора командной строки чаще всего применяется библиотека getoptlong (библиотека getopts.rb, обладающая менее развитой функциональностью, считается устаревшей). Она понимает однобуквенные и длинные флаги и распознает двойной дефис (--) как признак конца флагов. В целом библиотека ведет себя так же, как соответствующие функции GNU.

Необходимо создать объект класса GetoptLong, который и будет выполнять функции анализатора. Затем ему передаются допустимые значения флагов, а он извлекает их по одному.

У объекта-анализатора есть метод set_options, который принимает список массивов. Каждый массив содержит один или несколько флагов (в виде строк) и один «признак наличия аргумента», который говорит, должны ли эти флаги сопровождаться аргументами. Все флаги в одном массиве считаются синонимами; первый из них является «каноническим именем», которое и возвращает операция get.

Предположим, что имеется программа, понимающая следующие флаги: -h или --help (печать справки), -f или --file (указание имени файла), -l или --lines (вывод не более указанного числа строк, по умолчанию 100).

Такая программа могла бы начинаться следующим образом:

require "getoptlong"
parser = GetoptLong.new
parser.set_options(
 ["-h", "--help", GetoptLong::NO_ARGUMENT],
 ["-f", "--file", GetoptLong::REQUIRED_ARGUMENT],
 ["-l", "--lines", GetoptLong::OPTIONAL_ARGUMENT])

Теперь можно в цикле вызвать метод get (см. листинг 14.1). Наличие операторных скобок begin-end имитирует цикл с проверкой условия в конце. У метода get есть синоним get_option, существуют также итераторы each и each_option, которые в точности идентичны.

Листинг 14.1. Получение флагов из командной строки

filename = nil
lines = 0          # По умолчанию вывод не усекается.
loop do
 begin
  opt, arg = parser.get
  break if not opt
  # Только для отладки...
  puts (opt +" => " + arg)
  case opt
   when "-h"
    puts "Usage: ..."
    break          # Прекратить обработку, если задан флаг -h.
   when "-f"
    filename = arg # Запомнить аргумент - имя файла.
   when "-l"
    if arg != ""
     lines = arg   # Запомнить аргумент - число строк (если задан).
    else
     lines = 100   # Оставляемое по умолчанию число строк.
    end
  end
 rescue => err
  puts err
  break
 end
end
puts "имя файла = #{filename}"
puts "число строк = #{lines}"

Метод get возвращает nil, если флаг отсутствует, но пустую строку, если для флага не задан аргумент. Возможно, это ошибка.

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

• AmbiguousOption — указано сокращенное длинное имя флага, но сокращение не уникально;

• InvalidOption — неизвестный флаг;

• MissingArgument — для флага не задан аргумент;

• NeedlessArgument — указан аргумент для флага, который не должен сопровождаться аргументом.

Сообщения об ошибках обычно выводятся на stderr, но вывод можно подавить, присвоив акцессору quiet= значение true.

Библиотека getoptlong располагает и другими возможностями, которых мы здесь не обсуждали. Подробности вы найдете в документации.

Существуют другие библиотеки, например OptionParser, предлагающие несколько иную функциональность. Дополнительная информация приведена в архиве приложений Ruby.

Оглавление книги


Генерация: 1.467. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз