"Robert Klemme" <bob.news / gmx.net> wrote

> "Does it make sense to steal a method from a class and make it execute on
> another classes instance?"  I mean, you cannot generally expect that all
> methods the "stolen" method requires are present in the other class. (I
> know that's why you use the fallback but then again, what does one gain?
> You can, for exaple, inject methods temporarily into the other instance.)

I think this is how delegation is used in object-based languages like SELF.
It's a way for B to dynamically inherit at the object-level from A, both
behavior and state. Copying behavior would need copying state, which may not
be practical (how deep to copy, what about state change, etc.).

> > Does my desired behavior make sense (it does to me)?
>
> Apparently. :-)  But in what use case do you need this?  Although Ruby is
> amazingly dynamic not all features we can think of actually make sense.

I want to wrap one object (B) around another (A). B should get all of A's
behavior and state, customized by any methods on B. The behavior and state
of the A should be unchanged as it's methods may be invoked independently.

My specific use case needs a wide variety of ways of merging object graphs
(a bit like Joel's SuperHash, but deep + broad graphs and full control over
inheritance and merge rules). Given graphs g1,g2, I want to create their
merge g3:
  g3.delegate_to(g1, g2)
Then any property on g3 is either defined by a method on g3, or determined
by the logic of method_missing on g3. Which would delegate to g1, g2 and
merge their results ... with the CAVEAT that g1,g2 recursive calls for other
properties would always try g3 first.

Don't know if I explained it well. I'm sure I can find other approaches too,
like passing an explicit and optional _delegator_ parameter to all calls. I
was curious how well I could emulate SELF-like delegation as it would fit
very well.

> > btw, my guess at what the instance_eval version might look like:
> >
> > class B
> > def initialize delegatee
> >   @a = delegatee
> > end
> > def method_missing sym, *args, &block
> >  m = @a.method sym
> >  self.instance_eval m, *args, &block
> > end
> > end
>
> Won't work as far as  my experiements seem to indicate.

Correct. I meant "my guess at what the instance_eval version might look like
IF instance_eval worked for rebinding self for methods".

> Here's another idea: how about copying instance state around?

I would have to be very careful with that, due to state changes.

Thanks for the ideas!