[Xotcl] implementing delegation in Xotcl?
Gustaf Neumann
Gustaf.Neumann@wu-wien.ac.at
Mon, 18 Dec 2000 13:35:55 +0100 (CET)
>>>>> "CL" == Catherine Letondal <letondal@pasteur.fr> writes:
CL> Hi,
CL> I have a very philosophical question :-)
CL> I would like to replace inheritance by delegation for some
CL> classes' instances.
CL> e.g:
CL> Class C -parameter {delegate} # instead of Class C -superclass D
CL> C c -delegate a
CL> where a is an object of another class, say class A.
CL> Delegation means that:
CL> - next should call the delegate's proc/instproc
CL> - set, instvar would give access to delegate's variables
CL> (this is one of the classical delegation mechanisms/behaviour I believe?)
Dear Catherine,
Your definition is not the standard definition of delegation, since
delegation is not related with the ideas of "next". Informally,
delegation means: don't do everything by your[self], use another
object to help you. Normally, delegation is pretty much hardwired to
the code.
What you are trying to do is certainly very interesting. What you are
facing is however, the "inverse self problem" (Lieberman observed,
that through delegation, you easily loose the [self]-reference to the
callee, the method called via delegation has a different [self]; by
the means of mixins or filters, we tried to find alternate ways to
achieve, what delegation does, but now you seem to want delegation,
and you use filters and mixins, and you wonder how to get the self of
the delegate ... therefore i called the problem "inverse self
problem"). Somehow i doubt that you will be happy just by using
instvars in the delegate, i assume you want real delegation.
The problem is that by using "next", "mixins" etc. you do not change
the active object ([self]), which is certainly quite an important
assumption. I have to be convinced that this is too limited.
Below is a simple implementation, which can be made nicer by using
mixins or filters, but which is quite easy to understand and could
help you as a starting point. Most likely, you will want to use
"handleDelegation" for all methods, therefor a filter would be
appropriate, but maybe, you want to try delegation for a set of
methods, therefor you could use instmixins
Suppose, an object a1 of class A wants to call a method "m". Method m
has a stub for "m" that checks, whether it can delegate it (to object
d1 of D) and delegates it if possible, otherwise it handles it by
itself.
Note, that this works fine without to much interference with the
mixins/subclasses/... for A, a1, D, d1, instvars pose no problems,
etc. It is fairly trivial to extend this program to handle multiple
delegation objects...
best regards
-gustaf
=========================================================================
Class A -parameter delegate
A instproc handleDelegation {result} {
if {[[self] exists delegate]} {
set context [::info level -1]
# look for the called method in the delegated object
if {[[[self] set delegate] procsearch [lindex $context 0]] != ""} {
::upvar $result r
set r [eval [[self] set delegate] $context]
return 1
}
}
return 0
}
A instproc m {x} {
if {[[self] handleDelegation r]} {return $r} else {
puts "[self] [self class] [self proc] $x";
return [next]
}
}
Class D
D instproc m {x} {
puts "[self] [self class] [self proc] $x"
next
return [expr {$x*2 + [[self] set v]}]
}
D d1
d1 set v 100
A a1 -delegate d1
puts "result=[a1 m 123]"
=========================================================================