"Dave Baldwin" <dave.baldwin / 3dlabs.com> wrote > Having to prefix the ivar with self. makes the DSL look clunky I agree, though some experienced Rubyists don't see it that way. > so with this I can write > > Box {width 10} > > which is acceptable from the DSL view point, but makes the getter > operations more expensive. In the real version a getter operation takes > about 7 statements to allow for evaluation of block if the ivar had been > set to a Proc object and inheritance of values from its parent object (in > a visual hierarchy). The setter operation is often only done when the > object is created but the getter is done very frequently so I want to > move down the route of separate setters and getters rather than combining > them in the one method as an optimization. If you have some guarantees about the ordering of getters and setters, you can dynamically (re)define the getter and setter at the instance level. The attached worked for the case of instance variables being initialized only once, but being read at any time (the context for this was some kind of lazy creation of an object graph including forward references). Perhaps some bits of it will apply to your case. class Object def singleton_class class << self; self; end end end module LazyForwardRef UNDEFINED = nil def forward_ref(attr) getter = attr setter = (attr.to_s + '=').intern ivar = ('@' + attr.to_s).intern suspension = lambda { self.send getter } self.singleton_class.send :define_method, getter, lambda { v = instance_variable_get ivar if v == UNDEFINED suspension elsif v.is_a?(Proc) current = v.call self.send(setter, current) if current != v current else v end } self.singleton_class.send :define_method, setter, lambda {|val| self.instance_variable_set ivar, val } end end require 'pp' x = Object.new x.extend LazyForwardRef begin p x.foo rescue NoMethodError => detail pp detail pp [__LINE__, x, x.methods.sort - Object.instance_methods] end x.forward_ref(:foo) pp [__LINE__, x, x.methods.sort - Object.instance_methods] x.foo pp [__LINE__, x, x.foo] x.foo = 'Something else' pp [__LINE__, x, x.foo] y = Object.new y.extend LazyForwardRef y.forward_ref(:bar) pp [__LINE__, y, y.methods.sort - Object.instance_methods] z = Object.new z.extend LazyForwardRef z.forward_ref(:baz) y.bar = z.baz pp [__LINE__, x, y, z, x.foo, y.bar, z.baz, x.foo==z.baz] x.foo = y.bar pp [__LINE__, x, y, x.foo, y.bar] z.baz= 10 pp [__LINE__, x, y, z] pp [__LINE__, x.foo, y.bar, z.baz] pp [__LINE__, x, y, z]