В этом примере мы перехватываем исключения. Всего их может быть четыре:
•
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 является более сложный синтаксис. Кроме того, функциональность разнесена по различным классам, модулям и библиотекам.
Это послужило основанием для создания библиотеки
Shell
, которая упрощает, к примеру, организацию конвейеров команд и перенаправление вывода в файл. Кроме того, она сводит воедино функциональность из разных источников, скрывая ее за интерфейсом объекта
Shell
. (На платформе Windows эта библиотека работает не во всех случаях.)
14.3.1. Использование библиотеки Shell для перенаправления ввода/вывода
В классе
Shell
для создания объектов есть два метода:
new
и
cd
. Первый создает объект, ассоциированный с текущим каталогом, второй — объект, для которого рабочим будет указанный каталог.
require "shell"
sh1 = Shell.new # Работать в текущем каталоге.
sh2 = Shell.cd("/tmp/hal") # Работать в каталоге /tmp/hal.
Библиотека
Shell
определяет несколько встроенных команд (например,
echo
,
cat
и
tee
) в виде методов. Они всегда возвращают объекты класса
Filter
(как и определяемые пользователем команды, с которыми мы вскоре познакомимся).
Класс
Filter
понимает, что такое перенаправление ввода/вывода. В нем определены методы (или операторы)
<
,
>
и
|
, которые ведут себя примерно так, как мы ожидаем по многолетнему опыту написания shell-сценариев.
Если методу перенаправления передать в качестве параметра строку, то она будет считаться именем файла. Если же параметром является объект
IO
, он используется для операций ввода/вывода. Примеры: