if 0 {Richard Suchenwirth 2005-03-16 - Here's a little experiment in OO using the Jim feature that procs and lambdas can have a "closure" (a set of static variables) associated.
(Note that this code does not run on regular Tcl interpreters - use Jim instead!)
This way, the only physical location of an object is its lambda - rename it away as destructor. No namespaces needed (or possible in Jim ;^)}
#-- Here's a "constructor" the hard (bare-bones) way:
proc Account args { lambda {method args} {{balance 0}} {eval Account'$method $args} }
if 0 {Alternatively, if you want to use more than one class, here's factoring out the generic part:}
proc class {name instvars} { set body [list lambda {method args} $instvars] lappend body "eval $name'\$method \$args" proc $name args $body }
#-- Let's re-create a first class, the usual bank account, with one instance variable:
class Account { {balance 0} }
#-- Methods need to upvar the instance vars they need:
proc Account'deposit amount { upvar 1 balance balance set balance [+ $balance $amount] } proc Account'see {} { upvar 1 balance balance set balance } proc Account'withdraw amount { upvar 1 balance balance if {($balance-$amount)<0} {error "can only withdraw $balance"} set balance [- $balance $amount] puts "now: [[self] see]" }
if 0 {"Who am I?" is a deep philosophical question. Inside methods, it's easily answered:}
proc self {} {lindex [info level -2] 0}
if 0 {Now testing:
set a [Account] puts a:$a $a deposit 100 puts "deposit 100 -> [$a see]" $a withdraw 40 puts [$a see] catch {$a withdraw 1000} res puts $res
shows on stdout
a:<reference.<functio>.00000000000000000000> deposit 100 -> 100 now: 60 60 can only withdraw 60
SS Very nice! It seems to me a very natural hack to try to implement objects via closures. Also your way to do the dispatch is impressive ;)
Arts and crafts of Tcl-Tk programming | Category Object Orientation | Category Jim }