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?
GC quirks are nice to read about, but why not properly deallocate resources according to already existing language syntax?
Let me clarify that.
Image is destroyed after the block finishes executing. Just start a block, do all the image processing inside, then let the image destroy itself. This is analogous to the following C++ example:
There is very simple solution for your problem. Ruby design encourage you to do all actions in definite and clear way. No need for magic actions in constructor/destructor. Yes, constructors are required as a convenient way to assign initial state of object but not for "magic" actions. Let me illustrate this approach on possible solution. Goal, to keep image objects available but clean cache files of images.
To implement something similar to Python's context manager in Ruby:
In summary, what's going on here is that Manager is similar to using Python's with keyword. Manager is a high level class that receives Customer objects from the client, yields them back out, and explicitly destroys them at the end of its scope when the client is done using them (which is implicit from the client's perspective).
Ruby has
ObjectSpace.define_finalizer
to set finalizers on objects, but its use isn't exactly encouraged and it's rather limited (e.g. the finalizer can't refer to the object it is set for or else the finalizer will render the object ineligible for garbage collection).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)@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 currentself
. In Ruby 1.8, it seems that you cannot use anyproc
object converted (usingto_proc
) from a method that is bound toself
either. To make it work, you need aproc
object that doesn't capture the object you are defining the finalizer for.