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
, как если бы это был «настоящий файл».
С константой ARGF
ассоциирован метод file
— он возвращает объект IO
, соответствующий файлу, обрабатываемому в данный момент. Естественно, возвращаемое значение изменяется по мере перехода от одного файла к другому.
А если мы не хотим интерпретировать имена аргументов в командной строке как имена файлов? Тогда не надо обращаться к методам ввода без указания вызывающего объекта. Если вы хотите читать из стандартного ввода, укажите в качестве такого объекта STDIN
, и все будет работать правильно.
14.2.3. Константа ARGV
Глобальная константа ARGV
представляет список аргументов, переданных в командной строке. По сути дела, это массив.
n = ARGV.size
argstr = ''' + ARGV*',' + '''
puts 'Мне было передано аргументов: #{n}...'
puts 'Вот они: #{argstr}'
puts 'Заметьте, что ARGV[0] = #{ARGV[0]}'
Если запустить эту программу с аргументами red green blue
, то она напечатает:
Мне было передано аргументов: 3...
Вот они: 'red,green,blue'
Заметьте, что ARGV[0] = red
Ясно, что отдельно передавать число аргументов, как в былые времена, не нужно; эта информация — часть массива.
Привычных к старым соглашениям программистов может смутить также тот факт, что нулевой элемент массива — настоящий аргумент (а не, скажем, имя сценария). Нумерация аргументов начинается с нуля, а не с единицы, как в языке С и в различных интерпретаторах команд.
14.3. Библиотека Shell
Не всегда Ruby удобен в качестве языка сценариев. Например, в языке bash для запуска внешней программы достаточно просто указать ее имя безо всякого дополнительного синтаксиса.
Оборотной стороной мощи и гибкости Ruby является более сложный синтаксис. Кроме того, функциональность разнесена по различным классам, модулям и библиотекам.