Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

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

В соответствии с 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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top