Hi Paul,

Thanks a lot for the comprehensive information.  My responses are below.
============================================================================
Paul Brannan <pbrannan / atdesk.com> wrote:
---------------------------------------------------------------------
> In your case, the problem is not order of construction; it is order of
> registration with the garbage collector.

> You have the following requirements:
>   1. I needs to be constructed and registered with the GC.
>   2. O needs to be constructed and registered with the GC.
>   3. O cannot be fully constructed until I has been registered with the
>      GC.
>   4. I must not be freed by the GC until after O has been registered
>      with the GC.
>   5. You want all this to be as fast as possible.
>   6. You will have many I's (inner objects), and don't want to eat too
>      much memory on the stack with them.

> I hadn't considered requirement#4 before, and it throws me for a loop.
> There are a number of possible solutions, but it with mixing
> requirements 5 and 6 seems tricky.
---------------------------------------------------------------------

I have thought about this last night.  One problem with
"outer-to-inner" is (3), with the result of a lot of "if"'s in the mark
and free functions, which really does not support (5).  On the other hand,
using "inner-to-outer", we need to use stack in regards to (4), but one
problem is (6).  Also, suppose the number of VALUE's is not known at
compile time; putting a dynamic array of VALUE's in the stack will not
help, will it?  (Ruby just detects a VALUE pointer, not an array of
VALUE's)  Does this mean using "inner-to-outer" we have to create at
least a single stack/temporary VALUE variable of type Ruby Array to hold
all those I's temporarily?  (You see how complicated it may become for any
arbitrarily complex and deeply-nested data structure.)

---------------------------------------------------------------------
> I suspect that most C extensions are not "stress tested" like your
> extensions are; there could easily be bugs lurking in the corners.

> I also suspect that most C extensions wrap existing C structures, and do
> not have objects that hold references to other Ruby objects.  These
> extensions won't run into the problems you describe.

> Extensions that do hold references to other Ruby objects often do so
> through instance variables; these extensions also avoid the problems you
> are having.
---------------------------------------------------------------------

Totally agree.  It seems that even a fundamental problem like this is not
a fully-exploited field in Ruby.  I am wondering, because "writing C in
the presence of mark-and-sweep gc" looks like a general problem, how do
people outside Ruby do it?  (Just like the Gtk library, which shows an
example of object-inheritance format using C struct's and macros.)  I
think this is one more reason to create as much independence as possible
between the C-part and the Ruby-part, i.e., not only for performance, but
also to prevent bugs from happenning.

Regards,

Bill