Чтение онлайн

на главную - закладки

Жанры

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

Добавлен метод 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 и некоторые трюки, возможные в динамическом языке.

Пришло время вернуться в реальный мир. Ведь ООП — не самоцель, а всего лишь средство достижения цели. Последняя же заключается в написании эффективных, безошибочных и удобных для сопровождения приложений.

Поделиться:
Популярные книги

Воронцов. Перезагрузка. Книга 5

Тарасов Ник
5. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 5

Император Пограничья 1

Астахов Евгений Евгеньевич
1. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 1

Моров. Том 8

Кощеев Владимир
7. Моров
Фантастика:
альтернативная история
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Моров. Том 8

Лекарь Империи 10

Карелин Сергей Витальевич
10. Лекарь Империи
Фантастика:
городское фэнтези
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Лекарь Империи 10

Как я строил магическую империю 9

Зубов Константин
9. Как я строил магическую империю
Фантастика:
постапокалипсис
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Как я строил магическую империю 9

Кровь на эполетах

Дроздов Анатолий Федорович
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Кровь на эполетах

Личный аптекарь императора. Том 6

Карелин Сергей Витальевич
6. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Личный аптекарь императора. Том 6

Барон меняет правила

Ренгач Евгений
2. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон меняет правила

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Деревенщина в Пекине 3

Афанасьев Семен
3. Пекин
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Деревенщина в Пекине 3

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Простолюдин

Рокотов Алексей
1. Путь князя
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Простолюдин

Монстр

Кинг Стивен
Фантастика:
научная фантастика
8.22
рейтинг книги
Монстр

Адвокат Империи 4

Карелин Сергей Витальевич
4. Адвокат империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Адвокат Империи 4