TAO 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 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] } proc testGet {} { scope load ::myobj return $color } 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 } } }