Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
# Символы с интерполяцией:
alias_method :"old_#{meth}", :"#{meth}"
# Преобразование строк с помощью to_sym:
alias_method "old_#{meth}".to_sym, meth.to_sym
Чтобы обнаружить добавление нового метода класса в класс или модуль, можно определить метод класса singleton_method_added
внутри данного класса. (Напомним, что синглетный метод в этом смысле — то, что мы обычно называем методом класса, поскольку Class — это объект.) Этот метод определен в модуле Kernel
и по умолчанию ничего не делает, но мы можем переопределить его, как сочтем нужным.
class MyClass
def MyClass.singleton_method_added(sym)
puts "Добавлен метод #{sym.to_s} в класс MyClass."
end
def MyClass.meth1 puts "Я meth1."
end
end
def MyClass.meth2
puts "А я meth2."
end
В результате выводится следующая информация:
Добавлен метод singleton_method_added в класс MyClass.
Добавлен метод meth1 в класс MyClass.
Добавлен метод meth2 в класс MyClass.
Отметим, что фактически добавлено три метода. Возможно, это противоречит вашим ожиданиям, но метод singleton_method_added
может отследить и добавление самого себя.
Метод inherited
(из Class
) используется примерно так же. Он вызывается в момент создания подкласса.
class MyClass
def MyClass.inherited(subclass)
puts "#{subclass} наследует MyClass."
end
# ...
end
class OtherClass < MyClass
# ...
end
# Выводится: OtherClass наследует MyClass.
Можно также следить за добавлением методов экземпляра модуля к объекту (с помощью метода extend
). При каждом выполнении extend вызывается метод extend_object
.
module MyMod
def MyMod.extend_object(obj)
puts "Расширяется объект id #{obj.object_id}, класс #{obj.class}"
super
end
# ...
end
x = [1, 2, 3]
x.extend(MyMod)
# Выводится:
# Расширяется объект id 36491192, класс Array
Обращение к super
необходимо для того, чтобы мог отработать исходный метод extend_object
. Это напоминает поведение метода append_features
(см. раздел 11.1.12); данный метод годится также для отслеживания использования модулей.
11.3.14. Определение чистильщиков для объектов
У классов в Ruby есть конструкторы (методы new
и initialize
), но нет деструкторов (методов, которые уничтожают объекты). Объясняется это тем, что в Ruby применяется алгоритм пометки и удаления объектов, на которые не осталось ссылок (сборка мусора); вот почему деструктор просто не имеет смысла.
Однако тем, кто переходит на Ruby с таких языков, как C++, этот механизм представляется необходимым — часто задается вопрос, как написать код очистки уничтожаемых объектов. Простой ответ звучит так: невозможно сделать это надежно. Но можно написать код, который будет вызываться, когда сборщик мусора уничтожает объект.
а = "hello"
puts "Для строки 'hello' ИД объекта равен #{a.id}."
ObjectSpace.define_finalizer(а) { |id| puts "Уничтожается #{id}." }
puts "Нечего убирать."
GC.start
a = nil
puts "Исходная строка - кандидат на роль мусора."
GC.start
Этот код выводит следующее:
Для строки 'hello' ИД объекта равен 537684890.
Нечего убирать.
Исходная строка - кандидат на роль мусора.
Уничтожается 537684890.
Подчеркнем, что к моменту вызова чистильщика объект уже фактически уничтожен. Попытка преобразовать идентификатор в ссылку на объект с помощью метода ObjectSpace._id2ref
приведет к исключению RangeError
с сообщением о том, что вы пытаетесь воспользоваться уничтоженным объектом.
Имейте в виду, что в Ruby применяется консервативный вариант сборки мусора по алгоритму пометки и удаления. Нет гарантии, что любой объект будет убран до завершения программы.
Однако все это может оказаться и ненужным. В Ruby существует стиль программирования, в котором для инкапсуляции работы с ресурсами служат блоки. В конце блока ресурс освобождается, и жизнь продолжается без помощи чистильщиков. Рассмотрим, например, блочную форму метода File.open
:
File.open("myfile.txt") do |file|
line1 = file.read
# ...
end
Здесь в блок передается объект File
, а по выходе из блока файл закрывается, причем все это делается под контролем метода open
. Функциональное подмножество метода File.open
на чистом Ruby (сейчас этот метод ради эффективности написан на С) могло бы выглядеть так:
def File.open(name, mode = "r")
f = os_file_open(name, mode)
if block_given?
begin
yield f
ensure
f.close
end
return nil
else
return f
end
end
Мы проверяем наличие блока. Если блок был передан, то мы вызываем его, передавая открытый файл. Делается это в контексте блока begin-end
, который гарантирует, что файл будет закрыт по выходе из блока, даже если произойдет исключение.
11.4. Заключение
В этой главе были приведены примеры использования более сложных и даже экзотических механизмов ООП, а также решения некоторых рутинных задач. Мы видели, как реализуются некоторые паттерны проектирования. Познакомились мы и с API отражения в Ruby, продемонстрировали ряд интересных следствий динамической природы Ruby и некоторые трюки, возможные в динамическом языке.
Пришло время вернуться в реальный мир. Ведь ООП — не самоцель, а всего лишь средство достижения цели. Последняя же заключается в написании эффективных, безошибочных и удобных для сопровождения приложений.
В современном окружении таким приложениям часто необходим графический интерфейс. В главе 12 мы рассмотрим создание графических интерфейсов на языке Ruby.
Глава 12. Графические интерфейсы для Ruby
Нет ничего хуже четкого образа нечеткой идеи.
Апсель АдамсНет смысла отрицать, что мы живем в век графических интерфейсов (ГИ). В обозримом будущем тот или иной вид графического интерфейса станет основным способом взаимодействия с компьютерами.
Я не думаю, что командная строка не переживет следующее десятилетие — у нее есть свое место в мире. Но даже закоренелые хакеры прежних лет (предпочитающие команду cp -R
перетаскиванию файлов мышкой) все-таки не прочь воспользоваться ГИ, когда это оправданно.
Однако у графического программирования есть свои сложности. Главная проблема, конечно, состоит в том, чтобы определить, как должен выглядеть удобный интерфейс к программе; при проектировании интерфейсов картинка не всегда заменяет тысячу слов. В этой книге мы не можем уделить внимание данному аспекту, все-таки наша тема — не эргономика, не эстетика и не психология.
Вторая очевидная проблема в том, что графическое программирование сложнее. Надо учитывать форму, размер, положение и поведение всех находящихся на экране элементов управления, которыми можно манипулировать с помощью мыши и клавиатуры.
Читать дальшеИнтервал:
Закладка: