Деструктор объекта в Ruby (define_finalizer)
За удаление объектов в Ruby отвечает сборщик мусора. Момент когда будет уничтожен объект не известен, но произойдет это только после того как не останется ни одной ссылки на данный объект. Исходя из этого, прямой поддержки деструктора, в типичном его проявлении, в Ruby нет.
Однако мы можем подписаться на удаление любого объекта посредством метода ObjectSpace#define_finalizer, передав объект класса Proc, который будет вызван после уничтожения объекта.
Вот как мог бы выглядеть деструктор в Ruby
def initialize
ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc)
end
def Bar.finalize(id)
puts "Object #{id} dying at #{Time.new}"
end
end
b = Bar.new
Потребность в объявлении деструктора появляется когда мы хотим неявно высвободить ресурсы занятые в процессе работы объекта, попробуем приспособить описанную выше технику для симуляции деструктора в Ruby, это в какой то степени позволит нам писать свои классы в духе RAII.
Метод Bar.finalize будет вызван после того как объект bar уже уничтожен, однако те объекты которыми он владеет, на момент вызова finalize еще живы и стоят в очереди на уничтожение (при условии что на них никто больше не ссылается). Перепишем класс Bar следующим образом: в конструкторе мы создадим файл, который необходим удалить при разрушении объекта bar. Имя файла запомним в переменной объекта:
class Bar
def initialize(file_name)
@file_name = file_name.dup # запоминаем имя файла
FileUtils.touch(@file_name) # создаем файл
end
end
bar = Bar.new('temp.txt')
Теперь задача состоит в том как нам получить доступ в @file_name из деструктора. ObjectSpace#define_finalizer вторым параметром принимает объект типа Proc. Идея состоит в том чтобы продублировать имя файла и сохранить его в переданном объекте Proc, вот законченный вариант кода:
class Bar
def initialize(file_name)
@file_name = file_name.dup # запоминаем имя файла
FileUtils.touch(@file_name) # создаем файл
ObjectSpace.define_finalizer(self, Bar.finilazer(@file_name))
end
def Bar.finilazer(file_name)
lambda {
puts "Remove file '#{file_name}'"
FileUtils.rm(file_name) # удалим файл
}
end
end
b = Bar.new('temp.txt')
Данное решение можно обобщить, например в виде мексина, но оставим реализацию на усмотрение читателя, возможно вы захотите поделится и с нами.
// UPDATE 17.10.2008
Нашел в загашнеке продакшен код с использованием RAII:
module EDA
class Caddy
class Design < EDA::Design
attr_reader :connection
def initialize(eda, path)
super(eda)
openConnection(path)
end
def openConnection(path)
Comlib.checkFileOrError(path)
@connection = WIN32OLE.new('ADODB.Connection')
@connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=#{path};Jet OLEDB:Database Password=xxxxx;")
ObjectSpace.define_finalizer(self, Design.finalize(@connection))
end
private :openConnection
def self.finalize(connection)
lambda {
connection.Close
}
end
end
end
end

Обсуждение
Re: Деструктор объекта в Ruby
Спасибо, не знал о таком приеме, интересно.
линеечки для беременных
линеечки для новорожденных
Пример линеечки срок беременности: создать себе такую
Пример линеечки сколько лет ребеночку: создать себе такую
Пример линеечки женские: создать себе такую
![]()
Можете создать себе линеечки на форум или любой другой тематики. У нас большой выбор. Вставьте фотку своего машины и создайте привосходную линеечку.
линеечки детские для форумов
линеечки беременности
Пример линеечки срок беременности: создать себе такую
Пример линеечки сколько лет ребеночку: создать себе такую
Пример линеечки женские: создать себе такую
![]()
Можете создать себе линеечка для беременных или любой другой тематики. У нас огромный выбор. Вставьте фотку своего любимого и создайте великалепную линеечку.
Досуг калининград
Черные
- проститутки метро аэропорт
- черные проститутки
- элит проститутки
- проститутки бутова
Эскорт-услуги харьков
Красные
- фото девушек на улицах москвы
- алексеевская проститутки
- девочки индивидуалки москвы
- маленькая проститутка