Подтвердить что ты не робот

Уведомление об уничтожении объекта в Ruby

Я написал специальную модель Rails. Эта модель поддерживается на самом деле сервером не таблицей базы данных (поэтому она не наследуется от ActiveRecord::Base). Чтобы получить запрошенную информацию с сервера, я открываю ему SSH-соединение. Поскольку рельсы не повторно используют объект, новый объект, а также новое SSH-соединение с сервером будут созданы для получения любого запроса, который будет получен. Чтобы уменьшить нагрузку на сервер, я хочу закрыть соединение SSH, прежде чем объект модели получит собранный мусор. Я задаюсь вопросом, делает ли ruby ​​механизм уведомления, чтобы сообщить объекту, что он будет уничтожен? Если это так, я могу использовать это уведомление, чтобы узнать, когда закрыть соединения SSH. Если нет, мне нужно будет сделать это вручную, когда я знаю, что я закончил с объектом.

Если мне нужно вручную позаботиться об этом, могу ли я явно уничтожить объект? Или лучшее, что я могу сделать, это object = nil?

4b9b3361

Ответ 1

Если вам нужно контролировать, что происходит, когда объект уничтожается, вы действительно должны явно его уничтожать - это по дизайну. Вы не должны также явно уничтожать объект - это тоже по дизайну.

Другими словами, с точки зрения вашей программы объект никогда не уничтожается и не уничтожается. По этим причинам вы должны переосмыслить проблему (это не редкость - освобождение ресурсов, когда объект больше не нужен), поэтому он вписывается в парадигму Ruby.

Установка объекта в nil дает подсказку сборщику мусора, но не обязательно немедленно уничтожает его.

Однако, если вы должны обработать сборщик мусора, тогда прочитайте.

Нет прямой поддержки деструктора, но вы можете вызвать функцию функцию финализатора, когда она будет уничтожена.

Согласно http://pleac.sourceforge.net/pleac_ruby/classesetc.html, это может быть не сбор мусора, если он содержит ссылку на исходный объект, поэтому должен быть метод класса и а не метод экземпляра.

class MyClass
    def initialize
        ObjectSpace.define_finalizer(self,
                                     self.class.method(:finalize).to_proc)
    end
    def MyClass.finalize(id)
        puts "Object #{id} dying at #{Time.new}"
    end
end

Ответ 2

Я разместил решение здесь в другом потоке StackOverflow, который реализует Ruby таким образом, который аналогичен менеджеру контекста Python. С клиентской стороны уничтожение является неявным.