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

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

Жанры

Программирование на языке 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
, как если бы это был «настоящий файл».

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

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Законы Рода. Том 12

Мельник Андрей
12. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 12

Обгоняя время

Иванов Дмитрий
13. Девяностые
Фантастика:
попаданцы
5.00
рейтинг книги
Обгоняя время

Фишер. По следу зверя. Настоящая история серийного убийцы

Рогоза Александр
Реальные истории
Документальная литература:
истории из жизни
биографии и мемуары
5.00
рейтинг книги
Фишер. По следу зверя. Настоящая история серийного убийцы

Я еще не царь

Дрейк Сириус
25. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я еще не царь

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней

Адвокат Империи 7

Карелин Сергей Витальевич
7. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 7

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

#Бояръ-Аниме. Газлайтер. Том 13

Володин Григорий Григорьевич
13. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
фэнтези
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 13

Апокриф

Вайс Александр
10. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Апокриф

Любимая учительница

Зайцева Мария
1. совершенная любовь
Любовные романы:
современные любовные романы
эро литература
8.73
рейтинг книги
Любимая учительница

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Камень. Книга восьмая

Минин Станислав
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Камень. Книга восьмая

Романов. Том 4

Кощеев Владимир
3. Романов
Фантастика:
фэнтези
альтернативная история
5.00
рейтинг книги
Романов. Том 4