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

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

Жанры

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

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

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

Люди и нелюди

Бубела Олег Николаевич
2. Везунчик
Фантастика:
фэнтези
попаданцы
9.18
рейтинг книги
Люди и нелюди

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Петля, Кадетский корпус. Книга восьмая

Алексеев Евгений Артемович
8. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга восьмая

Курсант поневоле

Шелег Дмитрий Витальевич
1. Кровь и лёд
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Курсант поневоле

Чужак из ниоткуда 3

Евтушенко Алексей Анатольевич
3. Чужак из ниоткуда
Фантастика:
космическая фантастика
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 3

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8

Леди Малиновой пустоши

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.20
рейтинг книги
Леди Малиновой пустоши

Князь Андер Арес 2

Грехов Тимофей
2. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Андер Арес 2

Рубежник

Билик Дмитрий Александрович
1. Бедовый
Фантастика:
юмористическая фантастика
городское фэнтези
мистика
5.00
рейтинг книги
Рубежник

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

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

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

Мрак

Мартовский Кот
Фантастика:
постапокалипсис
5.00
рейтинг книги
Мрак