From: Alex Young Date: 2007-08-03T02:46:34+09:00 Subject: Re: finalizer not getting called Joshua Chia wrote: > evanwebb@gmail.com wrote: >> ... >> There is actually a simple reason. Remember that you're passing a >> block, ie. a closure, to define_finalizer. That closure holds on to >> the stuff like self, which in this case is the object to be finalized. >> Thus the finalizer code is actually keeping the object alive. >> >> Use define_finalizer outside the object associates the block with a >> context that does not contain the object to be finalized (once the >> local is set to nil), so it's actually garbage, and the finalizer >> runs. > > I'm not familiar with all the nuances for blocks, but I only see that > the block makes no reference to self. Why does it need to hold on to a > reference to self? > > With traditional C code, when you use a library, the client app often > needs to manually call init and teardown. With C++ and Java, you can > let the library do the init and teardown with constructors and > destructors, so you don't need to depend on the app to call init and > teardown at the right time. This is good from a software engineering > perspective since it reduces the number of things entangling the client > and library. > > I'm primarily concerned about the teardown happening at all and > secondarily about it happening as soon as possible. How do I guarantee > the eventual execution of some teardown code without depending on the > client (in this case, whoever initialized the instance)? Do I just move > the call to define_finalizer into another method and call that method > from initialize? The Ruby way is not to rely on a finalizer, but to define your setup and teardown code around a yield thus: class Foo def do_work setup_bits yield teardown_bits end end Then you use it like this: Foo.new.do_work do whatever_you_want end That way the execution sequence is - setup_bits - whatever_you_want - teardown_bits This is far simpler than relying on finalizer behaviour, which I find rather impenetrable. -- Alex