So I was curious to see how destructors work in Ruby, and...they don't. Or rather, the method we do have, ObjectSpace.define_finalizer, is rather restrictive. But it does leave a loophole -- the callback method receives an object_id.
If you're thinking this is a bad idea, you might be right -- this is just a proof of concept showing that it's possible. Anyway, so the main restriction on define_finalizer callback is it can't refer to the object being freed. If you try, the callback fails silently (except on JRuby 1.4.0! the exception propagates there). This is because the callback executes after the object has been freed, so there is no "self". Here's the proof of concept of one possible solution: maintain a map of object ids to resources: gist. The module, sample app, and output from Ruby 1.8(.7), 1.9, and JRuby 1.4.0 are also included.
Edit: apparently you can embed Gists. Sweet. Gist is below.