No registered users in community xowiki
in last 10 minutes
in last 10 minutes
[Xotcl] implementing delegation in Xotcl?
From: Catherine Letondal <letondal_at_pasteur.fr>
Date: Sun, 17 Dec 2000 23:13:34 +0100
Hi,
I have a very philosophical question :-)
I would like to replace inheritance by delegation for some classes' instances.
e.g:
Class C -parameter {delegate} # instead of Class C -superclass D
C c -delegate a
where a is an object of another class, say class A.
Delegation means that:
- next should call the delegate's proc/instproc
- set, instvar would give access to delegate's variables
(this is one of the classical delegation mechanisms/behaviour I believe?)
I have tried 3 methods, but neither work!
1) with a filter on C, which branch the methods calls to the appropriate location.
the filter is defined in init:
C filter CFilter
C instproc CFilter args {
::set m [[self] info calledproc]
[self] instvar delegate
if { ([C info instprocs $m] != "") || ([[self] info procs $m] != "") } {
puts "CFilter m=$m I do it myself"
next
} elseif { [info exists delegate] && ($m == "set" || $m == "instvar") } {
puts "CFilter m=$m I delegate it to $delegate"
eval $delegate $m $args
} elseif {[info exists delegate] && [[$delegate info class] info instprocs $m] != ""} {
puts "CFilter m=$m I delegate it to $delegate"
eval $delegate $m $args
} else {
puts "I dont know (m=$m), I call next"
next
}
}
2) with a mixin on c
in init:
[self] mixin [$delegate info class]
3) with both
=> problem with filter only (1) :
- next does not work the way I want (it does not call the delegates)
- set of delegates' variables works, but instvar don't
=> problem with mixin only (2)
- as the delegate's class is the mixin, it's it's methods which are always
called first (but I want the delegate's methods to be called only when
not existing for the class or when calling next)
- I need a method in the delegate's class for every method int the class
- delegate's variables are not available, of course (since I only use the
class of the delegate to inherit methods)
=> mixin+filter (3) (example below) :
- instvar does not work
Does someone have ideas and opinions about this? Has someone already tried?
I don't remeber having found something about it in Xotcl's papers (maybe I'm wrong?).
Thanks!
Date: Sun, 17 Dec 2000 23:13:34 +0100
Hi,
I have a very philosophical question :-)
I would like to replace inheritance by delegation for some classes' instances.
e.g:
Class C -parameter {delegate} # instead of Class C -superclass D
C c -delegate a
where a is an object of another class, say class A.
Delegation means that:
- next should call the delegate's proc/instproc
- set, instvar would give access to delegate's variables
(this is one of the classical delegation mechanisms/behaviour I believe?)
I have tried 3 methods, but neither work!
1) with a filter on C, which branch the methods calls to the appropriate location.
the filter is defined in init:
C filter CFilter
C instproc CFilter args {
::set m [[self] info calledproc]
[self] instvar delegate
if { ([C info instprocs $m] != "") || ([[self] info procs $m] != "") } {
puts "CFilter m=$m I do it myself"
next
} elseif { [info exists delegate] && ($m == "set" || $m == "instvar") } {
puts "CFilter m=$m I delegate it to $delegate"
eval $delegate $m $args
} elseif {[info exists delegate] && [[$delegate info class] info instprocs $m] != ""} {
puts "CFilter m=$m I delegate it to $delegate"
eval $delegate $m $args
} else {
puts "I dont know (m=$m), I call next"
next
}
}
2) with a mixin on c
in init:
[self] mixin [$delegate info class]
3) with both
=> problem with filter only (1) :
- next does not work the way I want (it does not call the delegates)
- set of delegates' variables works, but instvar don't
=> problem with mixin only (2)
- as the delegate's class is the mixin, it's it's methods which are always
called first (but I want the delegate's methods to be called only when
not existing for the class or when calling next)
- I need a method in the delegate's class for every method int the class
- delegate's variables are not available, of course (since I only use the
class of the delegate to inherit methods)
=> mixin+filter (3) (example below) :
- instvar does not work
Does someone have ideas and opinions about this? Has someone already tried?
I don't remeber having found something about it in Xotcl's papers (maybe I'm wrong?).
Thanks!
-- Catherine Letondal -- Pasteur Institute Computing Center +------------------------------------------------------------------------------------- Example of code for solution (3): # delegation with mixins+filter # object a of class A will be used as delegate for C Class A A instproc f1 args { puts "A f1 I am: [self] from class: [[self] info class]" } A instproc f3 args { puts "A f3 I am: [self] from class: [[self] info class]" } A a a set x 10 Class C -parameter {delegate} C instproc init args { [self] instvar delegate if {[info exists delegate] && [::Object isobject $delegate]} { puts "adding [$delegate info class] as a mixin for [self]" [self] mixin [$delegate info class] puts "adding CFilter as a filter for [[self] info class]" [[self] info class] filter CFilter } } C instproc f2 args { puts "C f2 I am: [self] from class: [[self] info class]" } C instproc f3 args { puts "C f3 I am: [self] from class: [[self] info class]" puts "calling next" next } C instproc CFilter args { ::set m [[self] info calledproc] if {$m == "CFilter"} { next } [self] instvar delegate if { ([C info instprocs $m] != "") || ([[self] info procs $m] != "") } { puts "CFilter m=$m I do it myself" next } elseif { [info exists delegate] && ($m == "set" || $m == "instvar") } { puts "CFilter m=$m I delegate it to $delegate" eval $delegate $m $args } elseif {[info exists delegate] && [[$delegate info class] info instprocs $m] != ""} { puts "CFilter m=$m I delegate it to $delegate" eval $delegate $m $args } else { puts "I dont know (m=$m), I call next" next } } C d -delegate a d proc f4 args { [self] instvar x puts "f4 [self] x: $x" } Try: d f1 d f2 d f3 d f4