Hello folks,

I have a question about Circular References in classes that I create 
from an extension that I've been playing with.  Since I'm very new to 
Ruby and much newer to extensions, after thinking about my problem for 
quite some time I decided it would probably be much more efficient to 
ask someone than try to figure it out myself.  So here goes.

At Apple's World Wide Developer's Conference in May, a presenter 
demonstrated a way to access the Quartz drawing system that is Part of 
Mac OS X from Python.  I thought that was pretty neat, but was having 
lots of fun with Ruby and thought it would be a pain to learn another 
scripting language.  Logically, of course, I decided that I might try 
to write my own extension for Ruby to do the same thing.

As part of working with that I have created two classes that wrap C 
structures commonly found in Quartz.  The first is CGSize whose C type 
looks something like:

struct CGSize
{
	float 		height;
	float		width;
};

The second is equally simple, CGPoint

struct CGPoint
{
	float		x;
	float		y;
}

No big deal.

The problem came in when I started looking at CGRect which is defined 
as:

struct CGRect
{
	CGPoint	origin;
	CGSize	size;
}

Now it seems likely that from ruby one might want to do something like 
this:

someRect = CGRect.make(0, 0, 100, 200);	# create a CGRect with it's 
origin at (0,0) and it's extent 100 points wide and 200 points tall
theSize = someRect.size;					# Get the size out of the rectangle.

When I create the CGRect object I use Data_Make_Struct.  When I want to 
return the size object out of that rectangle, my thought was to use 
Data_Wrap_Struct.

The thing that worries me is that the CGSize object I think I want to 
return from the "size()" method of the CGRect class would be wrapping a 
piece of the CGRect structure itself.  I'm concerned that should the 
CGRect be garbage collected that the CGSize object, which is an object 
wrapper around part of the CGRect's memory, will no longer be valid 
because the CGRect's memory was reclaimed.

In other words, the pointer to the memory that the CGSize object wraps 
will be halfway through the memory owned by the CGRect.  I'm worried 
that the system might dispose of the CGRect not knowing that the CGSize 
object still needs that memory.

I hope my concern is clear... I'm struggling to find the correct words 
to explain it.

At any rate, this leads to the following questions:

First, do I even need to worry about it?  Is the Garbage Collector in 
ruby clever enough to see that one of my objects has a pointer into the 
memory that makes up the CGRect object and, therefore, will not release 
the memory even though the CGRect object itself is not referenced?

If the Garbage Collector is not clever enough to do that, it seems 
reasonable that the CGRect object might create references to a CGPoint 
object and a CGSize object within itself.  At the same time, however, 
the CGPoint and CGSize objects want to keep a reference to the CGRect 
so that it's memory won't go away until they are done with it.  Will 
setting up that kind of circular reference prevent Ruby from being able 
to garbage collect the rectangle and it's point/origin pair?


Any insight would be appreciated.  I've you've made it this far, thank 
you for your time!

Scott Thompson