stooop sugar

tcleval: Little Sugar for Stooop object system:

it uses some internals of Stooop, but it is necessary coz stoop doesn't export a proc to tell the ancestors of a class. I need suggestions for this little sugar ^^.

#------------------------------------------------------------------------------

proc unknown {cmd args} {
    if {[string index $cmd 0] == "@"} {
        return [stooopSugar $cmd {*}$args]
    } else {
        error "unknown: $cmd $args"
    }
}



proc stooopSugar {cmd args} {
    set parts [split $cmd .]
    set this  [string range [lindex $parts 0] 1 end]
    set method [lindex $parts 1]

    set class [::stooop::classof $this]

   # first check if it is a class method
   if {[info procs ${class}::${method}] != ""} {
       return [${class}::${method} $this {*}$args]
   }

   # now checks if it is a ancestor method

    set baseClasses $::stooop::fullBases($class)

    foreach class $baseClasses {
        if {[info procs ${class}::${method}] != ""} {
             ${class}::${method} $this {*}$args
        } else {
            error "there is no suck method $method on class $class"
        }
    }
}

#------------------------------------------------------------------------------

Usage:


package require stooop 4                                  ;# load stooop package

namespace import stooop::*                ;# and import class, new, ... commands

class shape {                                           ;# base class definition
    proc shape {this x y} {                            ;# base class constructor
        set ($this,x) $x                           ;# data member initialization
        set ($this,y) $y
    }
    proc ~shape {this} {}                               ;# base class destructor
    # pure virtual draw: must be implemented in derived classes
    virtual proc draw {this}
    virtual proc rotate {this angle} {}                 ;# do nothing by default
}

proc shape::move {this x y} {            ;# external member procedure definition
    set ($this,x) $x
    set ($this,y) $y
    draw $this               ;# shape::draw invokes derived class implementation
    puts "and I moved to ($x,$y)"
}

class triangle {                                             ;# class definition
    proc triangle {this x y} shape {$x $y} {               ;# derived from shape
        # triangle constructor implementation
    }
    proc ~triangle {this} {}
    proc draw {this} {
        # triangle specific implementation
        puts "i am a triangle!!!"
    }
    proc rotate {this angle} {
        # triangle specific implementation
    }
}

class circle {}        ;# empty class definition, procedures are defined outside

proc circle::circle {this x y} shape {$x $y} {             ;# derived from shape
    # circle constructor implementation
}

proc circle::~circle {this} {}

proc circle::draw {this} {
    # circle specific implementation
    puts "I am a circle!!!"
}

# circle::rotate procedure is a noop, no need to overload



set s [new  circle 20 20]

@$s.draw 

@$s.move 10 20

set f [new triangle 10 20] 

@$f.move 20 25