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
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
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