[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