Чтение онлайн

на главную - закладки

Жанры

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

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.

14.2.2. Константа ARGF

Глобальная константа

ARGF
представляет псевдофайл, получающийся в результате конкатенации всех имен файлов, заданных в командной строке. Во многих отношениях она ведет себя так же, как объект
IO
.

Когда в программе встречается «голый» метод ввода (без указания вызывающего объекта), обычно имеется в виду метод, подмешанный из модуля

Kernel
(например,
gets
и
readlines
). Если в командной строке не задано ни одного файла, то по умолчанию источником ввода является объект
stdin
. Но если файлы заданы, то данные читаются из них. Понятно, что конец файла достигается в конце последнего из указанных файлов.

Если хотите, можете обращаться к

ARGF
явно:

# Скопировать все файлы на stdout.

puts ARGF.readlines

Быть может, вопреки ожиданиям, признак конца файла устанавливается после каждого файла. Так, предыдущий код выведет все файлы, а следующий — только первый файл:

until ARGF.eof?

 puts ARGF.gets

end

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

ARGF
операции
seek
и
rewind
, как если бы это был «настоящий файл».

Поделиться:
Популярные книги

Месть Паладина

Юллем Евгений
5. Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Месть Паладина

Кодекс Охотника. Книга XXXIX

Сапфир Олег
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIX

Запечатанный во тьме. Том 1. Тысячи лет кача

NikL
1. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 1. Тысячи лет кача

Ветер перемен

Ланцов Михаил Алексеевич
5. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ветер перемен

Барон переписывает правила

Ренгач Евгений
10. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Барон переписывает правила

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3

Сон для слабаков!

Дорничев Дмитрий
5. Моё пространственное убежище
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Сон для слабаков!

Телохранитель Генсека. Том 3

Алмазный Петр
3. Медведев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Телохранитель Генсека. Том 3

Маленькая женщина Большого

Зайцева Мария
5. Наша
Любовные романы:
эро литература
современные любовные романы
5.00
рейтинг книги
Маленькая женщина Большого

Император Пограничья 6

Астахов Евгений Евгеньевич
6. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 6

Моров. Том 7

Кощеев Владимир
6. Моров
Фантастика:
альтернативная история
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Моров. Том 7

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Зург 4: Я из будущего

Поселягин Владимир Геннадьевич
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
6.40
рейтинг книги
Зург 4: Я из будущего

Лихие. Авторитет

Вязовский Алексей
3. Бригадир
Фантастика:
альтернативная история
попаданцы
5.00
рейтинг книги
Лихие. Авторитет