I recall a mention a bit back about wanting to see more interesting
problems on ruby-talk. Let’s see if I can help out.
I have a system in which a Ruby script has a number of remote object
references (to a script in another process), identified by an object
with a unique string ID, which is used to make remote calls on or using
these objects. The system is all in place and is working fine- it’s
actually multi-way and each connection is bidirectional, but that is
unimportant for now.
I would like the script to be able to effectively ignore whether
something is remote or not, which means I’d like it to be able to pass
around these remote objects and be able to assume that once an object is
no longer used, it’ll just drop out of use and be garbage collected in
time, like everything else.
One problem: The store keeps a reference to the object in its Hash, for
use in lookups and incoming calls. Because of this, it’ll never be
collected. I’d like to somehow have it be collected if it’s just down to
one “reference”, and the information available to the store, so it knows
it can lose- or has just lost- the object.
The problem is essentially similar to the idea of weak pointers in a
reference-counted system- something by which you can hold a weak
reference that can detect, but doesn’t prevent, cleanup. If this was a
C++ problem, I’d be using Boost smart pointers, the store would use a
weak_ptr, and everything else would use a shared_ptr.
However, this doesn’t really make sense in a mark-and-sweep context, nor
does the idea of the object being “partially freeable” make sense, ie.
aware that it is just about to vanish or can be made free.
Any ideas as to a good way or suitable mechanisms to implement this? Is
there some way to look at an object and be able to detect that this is
the last reference that exists to the object in a script?
NB: I already have one idea- the Ruby script is embedded, so I might be
able to do something clever on the C/C++ side with Data_Wrap_Struct and
family, so that when a certain object is freed, I change something on
the C side, and the objects are stored in a container that doesn’t pass
on any of the mark calls. I’m not sure of the specifics yet, I’m sure
it’s quite possible, but I thought I’d just dig around for suggestions