Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
if File.new("myfile").stat.size?
puts "В файле есть данные."
else
puts "Файл пуст."
end
Методы zero?и size?включены также в модуль FileTest:
flag1 = FileTest::zero?("file1")
flag2 = FileTest::size?("file2")
Далее возникает следующий вопрос: «Каков размер файла?» Мы уже видели что для непустого файла метод size?возвращает длину. Но если мы применяем его не в качестве предиката, то значение nilтолько путает.
В классе Fileесть метод класса (но не метод экземпляра) для ответа на этот вопрос. Метод экземпляра с таким же именем имеется в классе File::Stat.
size1 = File.size("file1")
size2 = File.stat("file2").size
Чтобы получить размер файла в блоках, а не в байтах, можно обратиться к методу blocksиз класса File::Stat. Результат, конечно, зависит от операционной системы. (Метод blksizeсообщает размер блока операционной системы.)
info = File.stat("somefile")
total_bytes = info.blocks * info.blksize
10.1.12. Опрос специальных свойств файла
У файла есть много свойств, которые можно опросить. Мы перечислим в этом разделе те встроенные методы, для которых не нашлось другого места. Почти все они являются предикатами.
Читая этот раздел (да и большую часть этой главы), помните о двух вещах. Во-первых, так как класс Fileподмешивает модуль FileTest, то любую проверку, для которой требуется вызывать метод, квалифицированный именем модуля, можно также выполнить, обратившись к методу экземпляра любого файлового объекта. Во-вторых, функциональность модуля FileTestи объекта File::Stat(возвращаемого методом statили lstat) сильно перекрывается. В некоторых случаях есть целых три разных способа вызвать по сути один и тот же метод. Мы не будем каждый раз приводить все варианты.
В некоторых операционных системах устройства подразделяются на блочные и символьные. Файл может ссылаться как на то, так и на другое, но не на оба сразу. Методы blockdev?и chardev?из модуля FileTestпроверяют тип устройства:
flag1 = FileTest::chardev?("/dev/hdisk0") # false
flag2 = FileTest::blockdev?("/dev/hdisk0") # true
Иногда нужно знать, ассоциирован ли данный поток с терминалом. Метод tty?класса IO(синоним isatty) дает ответ на этот вопрос:
flag1 = STDIN.tty? # true
flag2 = File.new("diskfile").isatty # false
Поток может быть связан с каналом (pipe) или сокетом. В модуле FileTestесть методы для опроса этих условий:
flag1 = FileTest::pipe?(myfile)
flag2 = FileTest::socket?(myfile)
Напомним, что каталог — это разновидность файла. Поэтому нужно уметь отличать каталоги от обычных файлов, для чего предназначены два метода из модуля FileTest:
file1 = File.new("/tmp")
file2 = File.new("/tmp/myfile")
test1 = file1.directory? # true
test2 = file1.file? # false
test3 = file2.directory? # false
test4 = file2.file? # true
В классе Fileесть также метод класса ftype, который сообщает вид потока; одноименный метод экземпляра находится в классе File::Stat. Этот метод возвращает одну из следующих строк: file, directory, blockSpecial, characterSpecial, fifo, linkили socket(строка fifоотносится к каналу).
this_kind = File.ftype("/dev/hdisk0") # "blockSpecial"
that_kind = File.new("/tmp").stat.ftype # "directory"
В маске, описывающей режим файла, можно устанавливать или сбрасывать некоторые биты. Они не имеют прямого отношения к битам, обсуждавшимся в разделе 10.1.9. Речь идет о битах set-group-id, set-user-id и бите фиксации (sticky bit). Для каждого из них есть метод в модуле FileTest.
file = File.new("somefile")
info = file.stat
sticky_flag = info.sticky?
setgid_flag = info.setgid?
setuid_flag = info.setuid?
К дисковому файлу могут вести символические или физические ссылки (в тех операционных системах, где такой механизм поддерживается). Чтобы проверить, является ли файл символической ссылкой на другой файл, обратитесь к методу symlink?из модуля FileTest. Для подсчета числа физических ссылок на файл служит метод nlink(он есть только в классе File::Stat). Физическая ссылка неотличима от обычного файла — это просто файл, для которого есть несколько имен и записей в каталоге.
File.symlink("yourfile","myfile") # Создать ссылку
is_sym = FileTest::symlink?("myfile") # true
hard_count = File.new("myfile").stat.nlink # 0
Отметим попутно, что в предыдущем примере мы воспользовались методом класса symlinkиз класса Fileдля создания символической ссылки.
В редких случаях может понадобиться информация о файле еще более низкого уровня. В классе File::Statесть еще три метода экземпляра, предоставляющих такую информацию. Метод devвозвращает целое число, идентифицирующее устройство, на котором расположен файл. Метод rdevвозвращает целое число, описывающее тип устройства, а для дисковых файлов метод inoвозвращает номер первого индексного узла, занятого файлом.
file = File.new("diskfile")
info = file.stat
device = info.dev
devtype = info.rdev
inode = info.ino
10.1.13. Каналы
Ruby поддерживает разные способы читать из канала и писать в него. Метод класса IO.popenоткрывает канал и связывает с возвращенным объектом стандартные ввод и вывод процесса. Часто с разными концами канала работают разные потоки, но в примере ниже запись и чтение осуществляет один и тот же поток:
check = IO.popen("spell","r+")
check.puts("'T was brillig, and the slithy toves")
check.puts("Did gyre and gimble in the wabe.")
check.close_write
list = check.readlines
list.collect! { |x| x.chomp }
# list равно %w[brillig gimble gyre slithy toves wabe]
Отметим, что вызов close_writeобязателен, иначе мы никогда не достигнем конца файла при чтении из канала. Существует также блочная форма:
File.popen("/usr/games/fortune") do |pipe|
quote = pipe.gets
puts quote
# На чистом диске можно искать бесконечно. - Том Стил.
end
Если задана строка "-", то запускается новый экземпляр Ruby. Если при этом задан еще и блок, то он работает в двух разных процессах, как в результате разветвления (fork); блоку в процессе-потомке передается nil, а в процессе-родителе — объект IO, с которым связан стандартный ввод или стандартный вывод.
IO.popen("-")
do |mypipe|
if mypipe
puts "Я родитель: pid = #{Process.pid}"
listen = mypipe.gets
puts listen
else
puts "Я потомок: pid = #{Process.pid}"
end
end
# Печатается:
# Я родитель: pid = 10580
# Я потомок: pid = 10582
Метод pipeвозвращает также два конца канала, связанных между собой. В следующем примере мы создаем два потока, один из которых передает сообщение другому (то самое сообщение, которое Сэмюэль Морзе впервые послал по телеграфу). Если вы не знаете, что такое потоки, обратитесь к главе 3.
Интервал:
Закладка: