This page describes an upcoming enhancement to TclOO: Property tracking. Please stay tuned. The concept: Adding information that is tracked by class that allows the developer to embed data inside of classes **New Definition Keywords** The following keywords will be added to [oo::define]: : '''property''' ''field ?field...? value'' Set a property from the class definition. **New Introspection Tools** ***info class property*** : '''[info class] property''' ''class arguments...'' This method allows access to this class. Arguments that follow determine exactly what's done. '''[info class] property''' ''class'' '''get''' ''field ?field...?'': Return a value for a property, or die trying. '''[info class] property''' ''class'' '''getnull''' ''field ?field...?'': Return a value for a property, or an empty list if the value does not exist. '''[info class] property''' ''class'' '''exists''' ''field ?field...?'': Return true if a property exists '''[info class] property''' ''class'' '''list''' ''field ?field...?'': Return a list of keys below the level ''field ?field...?'' '''[info class] property''' ''class'' '''set''' ''field ?field...? value'': Add/modify a property ***info object property*** There will be an equivalent lookup based on objects. : '''[info object] property''' ''object arguments...'' This method provides objects access to the property database of their class. (Without the hassle of having to look up their class.) At present, it is read only. '''[info object] property''' ''object'' '''get''' ''field ?field...?'': Return a value for a property, or die trying. '''[info object] property''' ''object'' '''getnull''' ''field ?field...?'': Return a value for a property, or an empty list if the value does not exist. '''[info object] property''' ''object'' '''exists''' ''field ?field...?'': Return true if a property exists '''[info object] property''' ''object'' '''list''' ''field ?field...?'': Return a list of keys below the level ''field ?field...?'' **Usage** This system was originally intended to provide a Tk option-like database for TclOO objects. ====== # Dump the entire option dictionary set option_dict [info object [self] property get option] ====== ====== # Access a list of options set option_list [info object [self] property list option] ====== ====== # Check if an option exists set exists [info object [self] property exists option color] ====== ====== # Get the default value for color set color [info object [self] property getnull option color default] ====== ====== oo::define oo::class_withopts { constructor args { my InitializePublic {*}$args } method InitializePublic args { my variable config set optiondict [info object [self] property get option] # Populate config() with defaults foreach {field info} $optiondict { if {[info exists config($field)]} continue if {[dict exists $optiondict $field]} { set config($field) [dict get $optiondict default] } else { set config($field) {} } } foreach {field value} $args { set key [string trimleft $key -] if {![dict exists $optiondict $key]} { error "Bad option: $key, valid: [lsort -dictionary [dict keys $optiondict]]" } set config($field) $value } } method configure args { my variable config set triggers {} set optiondict [info object [self] property get option] foreach {key value} $args { set key [string trimleft $key -] if {![dict exists $optiondict $key]} { error "Bad option: $key, valid: [lsort -dictionary [dict keys $optiondict]]" } } foreach {key value} $args { set key [string trimleft $key -] if {$value != $config($key)} { set config($key) $value if {[dict exists $optiondict $field trigger]} { lappend triggers $field $value [dict get $optiondict $field set-script] } } } foreach {field value script] $triggers { eval [string map [list %object% [self] %self% [self] %field% $field %value% $value] $script] } } method cget field { set field [string trimleft $field -] if {![info object property [self] exists option $field]} { error "Invalid option $field, Valid [info option property [self] list option]" } my variable config return $config($field) } } ====== ---- '''[dkf] - 2015-04-13 10:12:43''' Thinking about this, I'm unhappy with an '''[info]''' subcommand being used to change the state. I know that '''info script''' does it, and that's pretty evil, but we don't need to do that elsewhere. Instead, properties should be editable or deletable via '''[oo::define]''' and '''[oo::objdefine]'''; that's how TclOO works for things that are considered to be “part of the definition”. We also want an easier way to read a property inside a method. Perhaps a '''property''' method? (Name can be changed; I just had to pick ''something''…) ====== method foo {} { set value [my property bar] # Do stuff with it… } ====== That method should return the currently applicable value of the property, where that means following the inheritance hierarchy to determine the value, just as with normal method overriding (though there's no method chain in this case). The implementation ''might'' cache things for speed. The name-space of properties is distinct from that of methods. '''[sdw] - 2015-05-28 09:40:00''' I have taken your suggestions to heart and simplified the concept a bit. In the new scheme, the "property" method provide's an object's interface to several helper functions (and a global array) run from the oo::meta namespace. <>Tcl Enhancements | TclOO