- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование на языке Ruby - Хэл Фултон
Шрифт:
Интервал:
Закладка:
file.flock(File::LOCK_SH) # Разделяемая блокировка (другие
# процессы могут сделать то же самое).
file.flock(File::LOCK_UN) # Разблокировать.
locked = file.flock(File::LOCK_EX | File::LOCK_NB)
# Пытаемся заблокировать файл, но не приостанавливаем программу, если
# не получилось; в таком случае переменная locked будет равна false.
Для семейства операционных систем Windows эта функция не реализована.
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
10.1.8. Буферизованный и небуферизованный ввод/вывод
В некоторых случаях Ruby осуществляет буферизацию самостоятельно. Рассмотрим следующий фрагмент:
print "Привет... "
sleep 10
print "Пока!n"
Если запустить эту программу, то вы увидите, что сообщения «Привет» и «Пока» появляются одновременно, после завершения sleep. При этом первое сообщение не завершается символом новой строки.
Это можно исправить, вызвав метод flush для опустошения буфера вывода. В данном случае вывод идет в поток $defout (подразумеваемый по умолчанию для всех методов Kernel, которые занимаются выводом). И поведение оказывается ожидаемым, то есть первое сообщение появляется раньше второго.
print "Привет... "
STDOUT.flush
sleep 10
print "Пока!n"
Буферизацию можно отключить (или включить) методом sync=, а метод sync позволяет узнать текущее состояние.
buf_flag = $defout.sync # true
STDOUT.sync = false
buf_flag = STDOUT.sync # false
Есть еще по крайней мере один низкий уровень буферизации, который не виден. Если метод getc возвращает символ и продвигает вперед указатель файла или потока, то метод ungetc возвращает символ назад в поток.
ch = mystream.getc # ?А
mystream.ungetc(?C)
ch = mystream.getc # ?C
Тут следует иметь в виду три вещи. Во-первых, только что упомянутая буферизация не имеет отношения к механизму буферизации, о котором мы говорили выше в этом разделе. Иными словами, предложение sync=false не отключает ее. Во-вторых, вернуть в поток можно только один символ; при попытке вызвать метод ungetc несколько раз будет возвращен только символ, прочитанный последним. И, в-третьих, метод ungetc не работает для принципиально небуферизуемых операций (например, sysread).
10.1.9. Манипулирование правами владения и разрешениями на доступ к файлу
Вопрос о владении файлами и разрешениях сильно зависит от платформы. Как правило, в системе UNIX функций больше, чем предоставляет Ruby, а на других платформах многие возможности не реализованы.
Для определения владельца и группы файла (это целые числа) класс File::Stat предоставляет методы экземпляра uid и gid:
data = File.stat("somefile")
owner_id = data.uid
group_id = data.gid
В классе File::Stat есть также метод экземпляра mode, который возвращает текущий набор разрешений для файла.
perms = File.stat("somefile").mode
В классе File имеется метод класса и экземпляра chown, позволяющий изменить идентификаторы владельца и группы. Метод класса принимает произвольное число файлов. Если идентификатор не нужно изменять, можно передать nil или -1.
uid = 201
gid = 10
File.chown(uid, gid, "alpha", "beta")
f1 = File.new("delta")
f1.chown(uid, gid)
f2 = File.new("gamma")
f2.chown(nil, gid) # Оставить идентификатор владельца без изменения.
Разрешения можно изменить с помощью метода chmod (у него также есть два варианта: метод класса и метод экземпляра). Традиционно разрешения представляют восьмеричным числом, хотя это и не обязательно.
File.chmod(0644, "epsilon", "theta")
f = File.new("eta")
f.chmod(0444)
Процесс всегда работает от имени какого-то пользователя (возможно, root), поэтому с ним связан идентификатор пользователя (мы сейчас говорим о действующем идентификаторе). Часто нужно знать, имеет ли данный пользователь право читать, писать или исполнять данный файл. В классе File::Stat есть методы экземпляра для получения такой информации.
info = File.stat("/tmp/secrets")
rflag = info.readable?
wflag = info.writable?
xflag = info.executable?
Иногда нужно отличить действующий идентификатор пользователя от реального. На этот случай предлагаются методы экземпляра readable_real?, writable_real? и executable_real?.
info = File.stat("/tmp/secrets")
rflag2 = info.readable_real?
wflag2 = info.writable_real?
xflag2 = info.executable_real?
Можно сравнить владельца файла с действующим идентификатором пользователя (и идентификатором группы) текущего процесса. В классе File::Stat для этого есть методы owned? и grpowned?.
Отметим, что многие из этих методов можно найти также в модуле FileTest:
rflag = FileTest::readable?("pentagon_files")
# Прочие методы: writable? executable? readable_real?
# writable_real? executable_real? owned? grpowned?
# Отсутствуют здесь: uid gid mode.
Маска umask, ассоциированная с процессом, определяет начальные разрешения для всех созданных им файлов. Стандартные разрешения 0777 логически пересекаются (AND) с отрицанием umask, то есть биты, поднятые в маске, «маскируются» или сбрасываются. Если вам удобнее, можете представлять себе эту операцию как вычитание (без занимания). Следовательно, если задана маска 022, то все файлы создаются с разрешениями 0755.
Получить или установить маску можно с помощью метода umask класса File. Если ему передан параметр, то он становится новым значением маски (при этом метод возвращает старое значение).

