** Variables in TclOO ** *** Variable Commands *** With TclOO, there are now three (or four!) [variable] commands. They are: * `'''::[variable]''' ''name''` * `'''::[variable]''' ''?name value?'' ''?...?''` Makes a namespace variable visible in the current scope. * `'''::[oo::define]''' ''$class'' '''variable''' ''?-slotOperation?'' ''?name ...?''` Makes an instance variable visible in all methods defined in the current class. * `'''::[oo::objdefine]''' ''$object'' '''variable''' ''?-slotOperation?'' ''?name ...?''` Makes an instance variable visible in all methods defined on the object. This can be thought of as a special case of `::oo::define::variable`. * `'''[my] variable''' ''?name ...?''` * `'''::[oo::object] variable''' ''?name ...?''` Makes an instance variable visible in the current scope. This is an unexported method of `::oo::object`, and equivalent to the following definition: ====== oo::define oo::object method variable {args} { foreach var $args { uplevel 1 [ list namespace upvar [namespace current] $var $var ] } } oo::define oo::object unexport variable ====== Another utility method on `oo::object` is (almost-)equivalently defined as: ====== oo::define oo::object method varname {name} { return [namespace current]::$name } ====== *** Where are my variables? *** Instance variables are just namespace variables in the object's namespace. So, inside a method: ====== my variable foo variable foo ====== both have the same effect. They differ importantly in how ''multiple arguments'' are treated, so be careful. One might prefer to use `my variable` in methods, as it more closely resembles `oo::define variable`. `oo::define` and `oo::objdefine` arrange that the variable is ''automatically'' made visible in all methods defined ''at the same level''. This is similar to having `variable ''name''` implicitly prepended to the methods' bodies. "At the same level" means simply that object variables are made visible in object methods (both defined with `[oo::objdefine]`), and class variables are made visible in methods on the same class (ie: not superclasses, subclasses or mixins). **** Choose Good Names **** When using inheritance or mixins, it's important to be aware that while `::[oo::define] variable` only makes a variable ''visible'' to methods in the current class, the variable will ''exist'' in the object's namespace. Thus collisions are possible, so beware: ====== oo::class create S { variable x method sx {} { set x 0 } } oo::class create M { variable x method mx {} { incr x 3 } } oo::class create C { superclass S mixin M variable x method cx {} { incr x 5 } } C create t puts [list [t sx] [t cx] [t mx] [t sx] [t cx] [t mx]] # => 0 5 8 0 5 8 ====== This sort of collision might be harmful if the author of `C` is unaware that `M` uses the name `x` for its own purposes. Thus, if you're publishing a class to use as a superclass or a mixin, the variables it uses should be considered part of the specification. For "private" data, short and likely-to-collide names should be avoided. It might be a good idea to contain it in a uniquely-named array or sub-object. Or perhaps a dict, or a coroutine! ** See Also ** * [Inspecting TclOO] * [TclOO] * http://www.magicsplat.com/articles/oo.html%|%APN's excellent TclOO Article%|% which calls these "data members" <>TclOO