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

10.1.7. Простой ввод/вывод

10.1.7. Простой ввод/вывод

Вы уже знакомы с некоторыми методами ввода/вывода из модуля Kernel; мы вызывали их без указания вызывающего объекта. К ним относятся функции gets и puts, а также print, printf и p (последний вызывает метод объекта inspect, чтобы распечатать его в понятном для нас виде).

Но есть и другие методы, которые следует упомянуть для полноты. Метод putc выводит один символ. (Парный метод getc не реализован в модуле Kernel по техническим причинам, однако он есть у любого объекта класса IO). Если параметром является объект String, то печатается первый символ строки.

putc(?n) # Вывести символ новой строки.
putc("X") # Вывести букву X.

Интересный вопрос: куда направляется вывод, если эти методы вызываются без указания объекта? Начнем с того, что в среде исполнения Ruby определены три глобальные константы, соответствующие трем стандартным потокам ввода/вывода, к которым мы привыкли в UNIX. Это STDIN, STDOUT и STDERR. Все они имеют тип IO.

Имеется также глобальная переменная $stdout, именно в нее направляется весь вывод, формируемый методами из Kernel. Она инициализирована значением STDOUT, так что данные отправляются на стандартный вывод, как и следовало ожидать. В любой момент переменной $stdout можно присвоить другое значение, являющееся объектом IO.

diskfile = File.new("foofile","w")
puts "Привет..." # Выводится на stdout.
$stdout = diskfile
puts "Пока!"     # Выводится в файл "foofile".
diskfile.close
$stdout = STDOUT # Восстановление исходного значения.
puts "Это все."  # Выводится на stdout.

Помимо метода gets в модуле Kernel есть методы ввода readline и readlines. Первый аналогичен gets в том смысле, что возбуждает исключение EOFError при попытке читать за концом файла, а не просто возвращает nil. Последний эквивалентен методу IO.readlines (то есть считывает весь файл в память).

Откуда мы получаем ввод? Есть переменная $stdin, которая по умолчанию равна STDIN. Точно так же существует поток стандартного вывода для ошибок ($stderr, по умолчанию равен STDERR).

Еще имеется интересный глобальный объект ARGF, представляющий конкатенацию всех файлов, указанных в командной строке. Это не объект класса File, хотя и напоминает таковой. По умолчанию ввод связан именно с этим объектом, если в командной строке задан хотя бы один файл.

# Прочитать все файлы, а затем вывести их.
puts ARGF.read
# А при таком способе более экономно расходуется память:
while ! ARGF.eof?
 puts ARGF.readline
end
# Пример: ruby cat.rb file1 file2 file3

При чтении из стандартного ввода (stdin) методы Kernel не вызываются. Потому можно обойти (или не обходить) ARGF, как показано ниже:

# Прочитать строку из стандартного ввода.
str1 = STDIN.gets
# Прочитать строку из ARGF.
str2 = ARGF.gets
# А теперь снова из стандартного ввода.
str3 = STDIN.gets

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

Оглавление статьи/книги

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