<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT size=2>
<P>Just over 6 months ago,Catherine Letondal raised</P>
<P>the issue of implementing "simple delegation".</P>
<P>Professor G. Neumann replied with some code showing</P>
<P>how it can be done as well as suggesting that one may</P>
<P>use a filter to filter all methods or an instmixin</P>
<P>to target specific methods for delegation.</P>
<P>I am now learning Tcl and XOTcl (a week or so now)at the</P>
<P>same time and have decided to try the filter approach.</P>
<P>The Experiment:</P>
<P>1. Create a meta-class SimpleDelegation</P>
<P>2. add a filter sdFilter to this meta-class</P>
<P>3. add an instproc setDelegate</P>
<P>4. Create classes A and B using SimpleDelegate</P>
<P>5. Create class C using Class</P>
<P>6. A has as delegate(instvar) an object of class B;</P>
<P>B has as delegate an object of class C</P>
<P>7. A,B and C has a method "m" defined</P>
<P>The Problem: (Using Windows binary ver 0.85)</P>
<P>I extended Prof. Neumann's code to handle above</P>
<P>and it works.(see Code1 below)</P>
<P>My experiment(Code 2) works only for the following</P>
<P>cases(that I tested):</P>
<P>1. A,B and C has a method "m".</P>
<P>2. The instvar delegate removed from B</P>
<P>It does not work when I rename the method</P>
<P>"m" in class C to "m2".</P>
<P>In this case I expect an object of class B to</P>
<P>execute "m" but instead I get an object of class</P>
<P>A executing "m" instead.</P>
<P>I would be grateful for any pointers to resolve</P>
<P>this problem.</P>
<P>Also I want to try to implement delegation as</P>
<P>described by Prof. Lieberman(OOPSLA 1986 paper).</P>
<P>Will be grateful for any pointers on this also.</P>
<P>...............</P>
<P>Code1: Prof Neumann's code inelegantly extended</P>
<P>Class A -parameter delegate</P>
<P>A instproc handleDelegation {result} {</P>
<P>if {[[self] exists delegate]} {</P>
<P>set context [::info level -1]</P>
<P>#look for method in delegated object</P>
<P>if {[[[self] set delegate] procsearch [lindex $context 0]] != "" } {</P>
<P>::upvar $result y</P>
<P>set y [eval [[self] set delegate] $context]</P>
<P>return 1</P>
<P>}</P>
<P>}</P>
<P>return 0</P>
<P>}</P>
<P>A instproc m {x} {</P>
<P>if {[[self] handleDelegation r]} {</P>
<P>return $r</P>
<P>} else {</P>
<P>puts "[self] [self class] [self proc] $x";</P>
<P>return [next]</P>
<P>}</P>
<P>}</P>
<P>Class B -parameter delegate</P>
<P>B instproc handleDelegation {result} {</P>
<P>if {[[self] exists delegate]} {</P>
<P>set context [::info level -1]</P>
<P>#look for method in delegated object</P>
<P>if {[[[self] set delegate] procsearch [lindex $context 0]] != "" } {</P>
<P>::upvar $result y</P>
<P>set y [eval [[self] set delegate] $context]</P>
<P>return 1</P>
<P>}</P>
<P>}</P>
<P>return 0</P>
<P>}</P>
<P>B instproc m {x} {</P>
<P>if {[[self] handleDelegation r]} {</P>
<P>return $r</P>
<P>} else {</P>
<P>puts "[self] [self class] [self proc] $x";</P>
<P>return [next]</P>
<P>}</P>
<P>}</P>
<P>Class D</P>
<P>D instproc m2 {x} {</P>
<P>puts "[self] [self class] [self proc] $x"</P>
<P>next</P>
<P>return [expr {$x*2 + [[self] set v]}]</P>
<P>}</P>
<P>D d1</P>
<P>d1 set v 100</P>
<P>B b1 -delegate d1</P>
<P>A a1 -delegate b1</P>
<P>puts "result = [a1 m 123]"</P>
<P>...............................................</P>
<P>Code2: My Try using filters</P>
<P>#create SimpleDelegation as a meta-class</P>
<P>Class SimpleDelegation -superclass Class</P>
<P>SimpleDelegation instproc sdFilter args {</P>
<P>set method [self calledproc]</P>
<P>if {[[self] exists delegate]} {</P>
<P>set del [[self] set delegate]</P>
<P>#if delegate has method then dispatch it.</P>
<P>if {[$del procsearch $method] != ""} {</P>
<P>return [eval [$del $method $args]]</P>
<P>} </P>
<P>return [next];</P>
<P>}</P>
<P>}</P>
<P>SimpleDelegation instproc init args {</P>
<P>[self] filterappend [self class]::sdFilter</P>
<P>next</P>
<P>[self] instproc setDelegate {d} {</P>
<P>[self] set delegate $d</P>
<P>}</P>
<P>}</P>
<P>SimpleDelegation A -parameter delegate</P>
<P>SimpleDelegation B -parameter delegate</P>
<P> </P>
<P>A instproc m {x} {</P>
<P>puts "[self] [self class] [self proc] $x"</P>
<P>return [next]</P>
<P>}</P>
<P>B instproc m {x} {</P>
<P>puts "[self] [self class] [self proc] $x"</P>
<P>next</P>
<P>return [expr {$x*2 + [[self] set v]}]</P>
<P>}</P>
<P>Class C</P>
<P>#method "m" renamed to "m2" here.</P>
<P>C instproc m2 {x} {</P>
<P>puts "[self] [self class] [self proc] $x"</P>
<P>next</P>
<P>return [expr {$x*3 + [[self] set v]}]</P>
<P>}</P>
<P>A a</P>
<P>B b</P>
<P>a setDelegate b</P>
<P>b set v 100</P>
<P>C c</P>
<P>b setDelegate c</P>
<P>c set v 100</P>
<P>puts "result = [a m 123]"</P>
<P>..................................................</P>
<P>Regards,</P>
<P>Sheik Yussuff</P>
<P>email: sheik@carib-link.net</P></FONT></DIV></BODY></HTML>