Питання Повідомлення про знищення об'єктів в Ruby


Я написав власну модель Rails. Цю модель підтримує фактично сервер, а не таблиця бази даних (так вона не успадковується від ActiveRecord::Base) Щоб отримати запитувану інформацію з сервера, я відкриваю для нього SSH-з'єднання. Оскільки рейки не повторно використовують об'єкт, новий об'єкт, а також нове SSH-з'єднання з сервером, буде створено для будь-якого запиту на отримання. Щоб зменшити навантаження на сервер, я хочу закрити SSH-з'єднання, перш ніж об'єкт моделі збирає сміття. Мені цікаво, чи робить рубій механізм сповіщення, щоб інформувати об'єкт про те, що він буде знищений? Якщо так, я міг би використовувати це сповіщення, щоб знати, коли закрити SSH-з'єднання. Якщо ні, мені доведеться робити це вручну, коли я знаю, що я закінчив з об'єктом.

Якщо мені потрібно впоратися з цим вручну, чи можу я явно знищити цей об'єкт? Або найкраще я можу це зробити object = nil?


16
2017-10-01 04:34


походження




Відповіді:


Якщо вам потрібно контролювати те, що трапляється, коли об'єкт знищено, ви повинні бути явно знищувати його самостійно - це за проектом. Ви не маєте наміру також однозначно знищувати об'єкт - це теж за проектом.

Іншими словами, з точки зору вашої програми об'єкт ніколи не руйнується чи не руйнується. З цих причин ви повинні переосмислити проблему (це не надзвичайна потреба - випуск ресурсів, коли об'єкт більше не потрібний), тому він вписується в парадигму 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

21
2017-10-01 04:45





Я опублікував рішення тут на іншому потоці StackOverflow, який реалізує Ruby таким самим чином, як і контекстний менеджер Python. З боку клієнта, знищення неявно.


0
2017-07-23 09:31