Ruby: Destructors?

Joern Akkermann picture Joern Akkermann · May 10, 2011 · Viewed 28.3k times · Source

I need to occasionaly create images with rmagick in a cache dir.

To then get rid of them fast, without loosing them for the view, I want to delete the image-files while my Ruby Instance of the Image-Class get's destructed or enters the Garbage Collection.

What ClassMethod must I overwrite to feed the destructor with code?

Answer

Su Zhang picture Su Zhang · Dec 20, 2012

@edgerunner's solution almost worked. Basically, you cannot create a closure in place of the define_finalizer call since that captures the binding of the current self. In Ruby 1.8, it seems that you cannot use any proc object converted (using to_proc) from a method that is bound to self either. To make it work, you need a proc object that doesn't capture the object you are defining the finalizer for.

class A
  FINALIZER = lambda { |object_id| p "finalizing %d" % object_id }

  def initialize
    ObjectSpace.define_finalizer(self, self.class.method(:finalize))  # Works in both 1.9.3 and 1.8
    #ObjectSpace.define_finalizer(self, FINALIZER)                    # Works in both
    #ObjectSpace.define_finalizer(self, method(:finalize))            # Works in 1.9.3
  end

  def self.finalize(object_id)
    p "finalizing %d" % object_id
  end

  def finalize(object_id)
    p "finalizing %d" % object_id
  end
end

a = A.new
a = nil

GC.start