TAO 8.6 no longer encapsulates data. It makes a copy of each variable for the local method call, but changes are not reflected in the state of the object automatically. Essentially all changes in state now have to go through cset. Why did I do this? Well, I was not getting consistently predictable results when a method could call another method. Anyone overly curious can see the Tao test suite for a breakdown on exactly what was going on. The flipside is that the copy only mechanism didn't end up breaking any existing Tao code. And it reduced the data encapsulation system to a simple loop: ::tao::class foo { static bat bing method bar {} { return $bat } } set obj [::tao::object_create #auto {class foo}] ## Magical incantation to introspect body of TclOO method ## ....start of body ... set this [self] set statevar [::tao::object_dict $this] dict for {var val} [dict get [set $statevar] vardata] { set $var $val } # END Preamble return $bat ...end of body... TAO 8.5 uses the "dict with" mechanism for data encapsulation. (Boring eh?) Each object has a global variable, and recursion is handled by a stack. If you were to peer inside of a compiled class: ::tao::class foo { variable bat bing method bar {} { return $bing } } set obj [::tao::new foo #auto] info body [::tao::class_nspace foo]::bar ....start of body ... set this [::tao::opeek] set statevar [::tao::object_dict $ dict with $statevar { return $bing } ...end of body... TAO 7.x uses a novel techique to handle data encapsulation, a "scope" command that lets one carry data around in bundles and unpack it on demand. Example: scope ::myobj add color variable scope ::myobj add type static myobj scope ::myobj add anArray hash proc testSet newcolor { scope load ::myobj set color $newcolor } proc testGet {} { scope load ::myobj return $color } # Will TRY to reprogram a static value # does not throw an error, but neither does it change # the state of the encapsulation proc testStaticSet ignoredVal { scope load ::myobj set type $ignoredVal } proc testStaticGet {} { scope load ::myobj set type $type } proc testArraySet {var val} { scope load ::myobj set anArray($var) $val } proc testArrayGet {var} { scope load ::myobj return [lindex [array get anArray $var] 1] } testSet green testGet > green testSet blue testGet > blue testArraySet height 20 testArrayGet height > 20 testStaticSet garbage # note that changes to "static" vars are not retained # this is actually correct testStaticGet > myobj '''Implementation''' There are a few pseudocode callouts that are required. One is "object_array", which maps an object name to a global variable. The others are 'get' which returns a value if it exists, or {} otherwise, ladd which adds a value to a list only if it is not present, and ldelete which removes an element from a list. proc scope {cmnd handle {varname {}} {type variable} {value NULL}} { upvar #0 [object_array $handle] state switch $cmnd { load { uplevel 1 [set state(script)] } add - del { array set vartypes [get state(info)] foreach vtype [array names vartypes] { ldelete vartypes($vtype) $varname } if { $cmnd == "add" } { ladd vartypes($type) $varname if { $value != "NULL" } { set state($varname) $value } } set state(info) [array get vartypes] scope rebuild $handle } rebuild { set statevar [object_array $handle] upvar #0 $statevar state array set meta [get state(info)] set script {} ### # this is really only for backward compadibility # with classes generated for itcl # enlightened clients will just call objdata(varname) # directly ### append script \n "\# LOAD ENCAPSULATED DATA" append script \n [list set statevar $statevar] set varlist {} lappend varlist ${statevar} objdata set usedvarnames {} set statics [get meta(static)] foreach {var} [get meta(hash)] { if { [lsearch $usedvarnames $var] >= 0 } continue ladd usedvarnames $var lappend varlist ${statevar}.${var} $var } foreach {var} [get meta(variable)] { if { [lsearch $usedvarnames $var] >= 0 } continue ladd usedvarnames $var lappend varlist ${statevar}($var) $var } foreach {globvar localvar} $varlist { if { [lsearch $statics $localvar] < 0 } { append script \n [list catch [list upvar #0 $globvar $localvar]] } } foreach {var} $statics { append script \n [list set $var [get ${statevar}($var)]] } set state(script) $script } } } ---- [Category Design] [Category Object Orientation]