[itsme213 <itsme213 / hotmail.com>, 2005-01-06 08.01 CET]
> Consider the following Ruby object graph being constructed. It has forward
> references in line (2) and (3) to x.forward_ref, something that will only
> come into existence in line (7). It has a reference in line (4) and (5) to
> an as-yet unresolved forward reference from line (2). And it operates on an
> unresolved reference on line (6).
> 
> 1) x = OpenStruct.new
> 2) y = OpenStruct.new(:f0 => x, :f1=>x.forward_ref)
> 3) z = [x, y, x.forward_ref]
> 4) w = y.f1
> 5) foo(y.f1)
> 6) bar(y.f1.f2)
> 7) x.forward_ref = Object.new
> 
> I want to build such structures lazily, but be lazy only when the laziness
> is needed i.e. not for :f0=>x, or [x, y, ...], or y.f1. And I would like to
> force resolution of (selected or all) unresolved references either:
> a) at a time of my choosing (raising exceptions if needed), or
> b) incrementally whenever a given reference becomes resolvable, or
> c) when something is done with that reference i.e. some method invoked on it
> (line 6).

Why not delegators?

Anyway, I can't make the delegator to reinitialize with a new object :(.
Need to study delegators... I don't even know what's happening in my code!

require 'delegate'

class RawOpenStruct
	def method_missing name, *args
		name = name.id2name
		setter = name.sub!(/=$/, "")
		iv = "@"+name
		if instance_variables.include? iv
			del = instance_variable_get(iv)
			if setter
				del.__send__ :initialize, args.first
			else
				return del
			end
		else
			if setter
				del = SimpleDelegator.new args.first
			else
				del = SimpleDelegator.new MySuperVivifier.new
				del.__getobj__.__setdelegator__ del
			end
			return instance_variable_set(iv, del)
		end
	end
end

class MySuperVivifier
	def method_missing name, *args
		# vivify!
		name = name.id2name
		# the following __send__ :initialize only sets the object
		# it doesn't create the methods.
		# and also the methods __setdelegator__ and method_missing
		# should be deleted
		# I need study delegators :))
		@delegator.__send__ :initialize, 42
		
		@delegator.__getobj__.__send__ name.to_sym, *args
	end
	
	def __setdelegator__ delegator
		@delegator=delegator
	end
end

x = RawOpenStruct.new
y = RawOpenStruct.new
y.f1 = x.forward_ref
z = [x, y, x.forward_ref]
w = y.f1
p y.f1
p y.f1 + 34
p y.f1.methods
p y.f1.class
p y.f1.class.ancestors
p y.f1.size # BOOM!
x.forward_ref = Object.new