Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
pipe = IO.pipe
reader = pipe[0]
writer = pipe[1]
str = nil
thread1 = Thread.new(reader,writer) do |reader,writer|
# writer.close_write
str = reader.gets
reader.close
end
thread2 = Thread.new(reader,writer) do |reader,writer|
# reader.close_read
writer.puts("What hath God wrought?")
writer.close
end
thread1.join
thread2.join
puts str # What hath God wrought?
10.1.14. Специальные операции ввода/вывода
В Ruby можно выполнять низкоуровневые операции ввода/вывода. Мы только упомянем о существовании таких методов; если вы собираетесь ими пользоваться, имейте в виду, что некоторые машиннозависимы (различаются даже в разных версиях UNIX).
Метод ioctl
принимает два аргумента: целое число, определяющее операцию, и целое число либо строку, представляющую параметр этой операции.
Метод fcntl
также предназначен для низкоуровневого управления файловыми потоками системно зависимым образом. Он принимает такие же параметры, как ioctl
.
Метод select
(в модуле Kernel
) принимает до четырех параметров. Первый из них — массив дескрипторов для чтения, а остальные три необязательны (массив дескрипторов для записи, дескрипторов для ошибок и величина тайм-аута). Если на каком-то из устройств, дескрипторы которых заданы в первом массиве, оказываются новые данные для чтения или какое-то из устройств, дескрипторы которых перечислены во втором массиве, готово к выполнению записи, метод возвращает массив из трех элементов, каждый из которых в свою очередь является массивом, где указаны дескрипторы устройств, готовых к выполнению ввода/вывода.
Метод syscall
из модуля Kernel
принимает по меньшей мере один целочисленный параметр (а всего до девяти целочисленных или строковых параметров). Первый параметр определяет выполняемую операцию ввода/вывода.
Метод fileno
возвращает обычный файловый дескриптор, ассоциированный с потоком ввода/вывода. Это наименее системно зависимый из всех перечислениях выше методов.
desc = $stderr.fileno # 2
10.1.15. Неблокирующий ввод/вывод
«За кулисами» Ruby предпринимает согласованные меры, чтобы операции ввода/вывода не блокировали выполнение программы. В большинстве случаев для управления вводом/выводом можно пользоваться потоками — один поток может выполнить блокирующую операцию, а второй будет продолжать работу.
Это немного противоречит интуиции. Потоки Ruby работают в том же процессе, они не являются платформенными потоками. Быть может, вам кажется, что блокирующая операция ввода/вывода должна приостанавливать весь процесс, а значит, и все его потоки. Это не так — Ruby аккуратно управляет вводом/выводом прозрачно для программиста.
Но если вы все же хотите включить неблокирующий режим ввода/вывода, такая возможность есть. Небольшая библиотека io/nonblock
предоставляет методы чтения и установки для объекта IO
, представляющего блочное устройство:
require 'io/nonblock'
# ...
test = mysock.nonblock? # false
mysock.nonblock = true # Отключить блокирующий режим.
# ...
mysock.nonblock = false # Снова включить его.
mysock.nonblock { some_operation(mysock) }
# Выполнить some_operation в неблокирующем режиме.
mysock.nonblock(false) { other_operation(mysock) }
# Выполнить other_operation в блокирующем режиме.
10.1.16. Применение метода readpartial
Метод readpartial
появился сравнительно недавно с целью упростить ввод/вывод при определенных условиях. Он может использоваться с любыми потоками, например с сокетами.
Параметр «максимальная длина» (max length) обязателен. Если задан параметр buffer, то он должен ссылаться на строку, в которой будут храниться данные.
data = sock.readpartial(128) # Читать не более 128 байтов.
Метод readpartial
игнорирует установленный режим блокировки ввода/вывода. Он может блокировать программу, но лишь при выполнении следующих условий: буфер объекта IO пуст, в потоке ничего нет и поток еще не достиг конца файла.
Таким образом, если в потоке есть данные, то readpartial
не будет блокировать программу. Он читает не более указанного числа байтов, а если байтов оказалось меньше, то прочитает их и продолжит выполнение.
Если в потоке нет данных, но при этом достигнут конец файла, то readpartial
немедленно возбуждает исключение EOFError
.
Если вызов блокирующий, то он ожидает, пока не произойдет одно из двух событий: придут новые данные или обнаружится конец файла. Если поступают данные, метод возвращает их вызывающей программе, а в случае обнаружения конца файла возбуждает исключение EOFError
.
При вызове метода sysread
в блокирующем режиме он ведет себя похоже на readpartial
. Если буфер пуст, их поведение вообще идентично.
10.1.17. Манипулирование путевыми именами
Основными методами для работы с путевыми именами являются методы класса File.dirname
и File.basename
; они работают, как одноименные команды UNIX, то есть возвращают имя каталога и имя файла соответственно. Если вторым параметром методу basename
передана строка с расширением имени файла, то это расширение исключается.
str = "/home/dave/podbay.rb"
dir = File.dirname(str) # "/home/dave"
file1 = File.basename(str) # "podbay.rb"
file2 = File.basename(str,".rb") # "podbay"
Хотя это методы класса File
, на самом деле они просто манипулируют строками.
Упомянем также метод File.split
, который возвращает обе компоненты (имя каталога и имя файла) в массиве из двух элементов:
info = File.split(str) # ["/home/dave","podbay.rb"]
Метод класса expand_path
преобразует путевое имя в абсолютный путь. Если операционная система понимает сокращения ~
и ~user
, то они тоже учитываются.
Dir.chdir("/home/poole/personal/docs")
abs = File.expand_path("../../misc") # "/home/poole/misc"
Если передать методу path
открытый файл, то он вернет путевое имя, по которому файл был открыт.
file = File.new("../../foobar")
name = file.path # "../../foobar"
Константа File::Separator
равна символу, применяемому для разделения компонентов путевого имени (в Windows это обратная косая черта, а в UNIX — прямая косая черта). Имеется также синоним File::SEPARATOR
.
Метод класса join
использует этот разделитель для составления полного путевого имени из переданного списка компонентов:
path = File.join("usr","local","bin","someprog")
# path равно "usr/local/bin/someprog".
# Обратите внимание, что в начало имени разделитель не добавляется!
Не думайте, что методы File.join
и File.split
взаимно обратны, — это не так.
10.1.18. Класс Pathname
Следует знать о существовании стандартной библиотеки pathname
, которая предоставляет класс Pathname
. В сущности, это обертка вокруг классов Dir
, File
, FileTest
и FileUtils
, поэтому он комбинирует многие их функции логичным и интуитивно понятным способом.
Интервал:
Закладка: