Notification of Object Destruction in Ruby

Notification of object destruction in Ruby

If you need to control what happens when an object is destroyed, you really should be explicitly destroying it yourself - this is by design. You're not supposed to be able to destroy an object explicitly either - this is also by design.

In other words, from the perspective of your program, an object is never destroyed or destroyable. For these reasons you should re-think the problem (this is not an uncommon need - release of resources when the object is no longer needed) so it fits into the Ruby paradigm.

Setting the object to nil gives a hint to the garbage collector, but does not necessarily immediately destroy it.

However, if you must have the garbage collector handle it, then read on.

There is no direct support for a destructor, but you can have it call a finalizer function when it is destroyed.

According to http://pleac.sourceforge.net/pleac_ruby/classesetc.html it may not be garbage collected if it contains a reference to the original object, so must be a class method and not an instance method.

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

Ruby: Destructors?

You can use ObjectSpace.define_finalizer when you create the image file, and it will get invoked when the garbage man comes to collect. Just be careful not to reference the object itself in your proc, otherwise it won't be collected by the garbage man. (Won't pick up something that's alive and kicking)

class MyObject
def generate_image
image = ImageMagick.do_some_magick
ObjectSpace.define_finalizer(self, proc { image.self_destruct! })
end
end

How to destroy Ruby object?

Other than hacking the underlying C code, no. Garbage collection is managed by the runtime so you don't have to worry about it. Here is a decent reference on the algorithm in Ruby 2.0.

Once you have no more references to the object in memory, the garbage collector will go to work. You should be fine.

ruby equivalent of destructor

There is a hook called ObjectSpace.define_finalizer that is called when an object is destroyed.

Is there a way to destroy *self* after a class is instantiated?


Ruby Finalizers Aren't Really Destructors

While you can define finalizers for Ruby objects, they aren't really destructors as such. In fact, they aren't triggered until after the object is destroyed. The docs say:

define_finalizer(obj, aProc=proc())

Adds aProc as a finalizer, to be called after obj was destroyed.

Rethink Your Approach

Rather than instantiating your browser instance with #new, consider a pattern more like:

class Something
attr_accessor :browser

def start_browser
end

def quit_browser
end
end

s = Something.new
s.start_browser
s.quit_browser

Other patterns are also possible, including setting callbacks or timers within your object. Ultimately, the point is that objects should go out of scope and be garbage collected---they can't actually destroy themselves.

Rails - destroy associations from object with condition

Just remove @foo.bars.each{|b| b.update_attribute(:blub_id, nil)} and make another try. I supposed that blub_id is a foreign key that indicates to which foo the current bar belongs to.

When you make the blub_id is equal to null, the records with a blub_id null is belongs to nothing and then @foo.bars.where(type: "test").destroy_all doesn't include these bars.

Check if ActiveRecord object is destroyed using the .destroy() return value

If you're unsure, you can use destroyed? method. Return value of destroy is undocumented, but it returns just freezed destroyed object (you cannot update it). It doesn't return status of destroy action.

Although generally destroying object should always succeed, you can listen for ActiveRecordError. For example Optimistic Locking can raise ActiveRecord::StaleObjectError on record destroy.

Send async email about destroyed objects

When deleting an object and sending an email is such tightly coupled, you can create a sidekiq job which does both things. So you have only to send an id to the job. The sidekiq job deletes your object and sends the email synchronous, within the job. For your request the mail is still send asynchron.

`marked_for_destruction?' for false:FalseClass

If I understand well your notification system, you try to send a notif to admins every time a Leave is created.

Assuming that, your error comes from your recipients method:
[user.admin] returns [true] or [false]

and when you iterate on it, you do: Notification.create(recipient: true/false, ...)

You can fix your system by creating a user scope for admins:

class User < ApplicationRecord
#...
scope :admins, -> { where(admin: true) }
end

and change the recipients method like:

class Leave < ApplicationRecord
#...
private

def recipients
User.admins
end

def create_notifications
#...
end
end


Related Topics



Leave a reply



Submit