From: Csaba Henk Date: 2005-04-03T01:54:44+09:00 Subject: Re: how to simulate self-style delegation On 2005-04-01, itsme213 wrote: > I have classes A and B. > > class A > def x > "A::x " > end > def xy > self.x + "A::y" > end > end > > class B > def initialize a > @a = a > end > def x > "B::x " > end > def method_missing ??? > ?? SELF-style delegate to @a > end > end > > I want true SELF-style delegation from objects of class B to A. i.e. self > calls on an A are in the context of the delegating B (if any). > > a = A.new > a.xy #=> "A::x A::y" > > b = B.new a > > b.xy #=> "B::x A::y" > # calls b.method missing > # calls a.xy > # calls b.x #=> "B::x" > # calls a.y #=> "A::y" > # return "B::x A::y" > > How can I do this? What I can imagine: 1) * create a joint proxy object for a and b (something along the lines of the cuckoo of http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/128368, just the method_missing of the proxy should look at both a and b) * copy all instance_variables of b to the proxy * define a method_missing for b which resends the message :xy to the proxy object (somehow you should exclude circular method_missing calls between b and the proxy) This work by-and-large as long as you don't overwrite instance variables in b. If you have an instance variable which gets overwritten frequently, make a custom setter for it which updates the proxy as well. or 2) * Make A a module which extends itself * define A.new similarly to this: def new a = Module.new a.send :include, self a.extend a end Now A quacks like a class. * in B.initialize, extend the instance with a. However, it pulls in the whole A "instance", and delegation is not limited to #xy. Csaba