From: Assaph Mehr Date: 2005-01-07T08:41:29+09:00 Subject: Re: Ruby design question: lazy construction of object graph containing forward references Here's an implementation of lazy forward references. Notice that if you assign to a variable before reading it, the previous lazy initialization will be overwritten. __BEGIN CODE__ class Object def singleton_class class << self; self; end end end module LazyForwardRef def forward_ref(meth, &bl) self.singleton_class.send :define_method, meth, lambda{ self.singleton_class.send :define_method, meth, lambda { self.singleton_class.send :attr_accessor, meth instance_variable_set "@#{meth}", bl.call } return send(meth) } self.singleton_class.send :define_method, "#{meth}=", lambda{ |args| self.singleton_class.send :define_method, meth, lambda { self.singleton_class.send :attr_accessor, meth instance_variable_set "@#{meth}", *args } return send(meth) } end end require 'pp' x = Object.new x.extend LazyForwardRef begin p x.foo rescue NoMethodError => detail pp detail pp [x, x.methods.sort - Object.instance_methods] end x.forward_ref(:foo) { Hash[1,2,3,4] } pp [x, x.methods.sort - Object.instance_methods] p x.foo pp [x, x.methods.sort - Object.instance_methods] x.foo = 'Something else' pp x p x.foo puts "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n" y = Object.new y.extend LazyForwardRef y.forward_ref(:bar) { [1,2,3,4] } pp [y, y.methods.sort - Object.instance_methods] y.bar= 10 pp [y, y.methods.sort - Object.instance_methods] p y.bar