From: "Florian G. Pflug" Date: 2001-08-12T21:35:08+09:00 Subject: [ruby-talk:19595] Re: Forced garbage collection On Sun, Aug 12, 2001 at 08:11:22PM +0900, Lars Christensen wrote: > I tried adding a finalizer on a object from its own methods, i.e. > > ObjectSpace.define_finalizer(self) { > puts 'finalized'; > } > > The finalizer never gets called :(. Only if i do it externally to the > object, it works: > > ObjectSpace.define_finalizer(someObject) { > puts 'finalized'; > } I has the same problem. It works, if you use a _class_method_ as finalizer. e.g. class Foo def initialize() ObjectSpace::define_finalizer(self, Foo.finalizer(@important_var_1, @important_var_2, ...)) end def Foo.finalize(*some_important_instance_vars) return lambda { do_cleanup(*some_important_instance_vars) } end end I think this is because: .) Block are "true closures". This means the remeber the context in which they were created. If you pass a block from an instance method to e.g define_finalizer(), the some information about the instance is saved with the block (you can access instance variables in the block, so this information is needed). And of course the garbage collector knows that the block still references the instance, and therefore the instance has to deleted _after_ the block. .) The finalizer is called _after_ the object was destructed. But if the finalizer depend on the instance - which it does if it is a block created in an instance method - the finalizer would need to be called _before_ the object is deleted. This is a sort of deadlock, which ruby seems to overcome by not calling the finalizer... Well, at least this was what I thought when I discovered this behaviour. Please correct me if my assumptions are wrong. greetings, Florian Pflug