Variables in TclOO edit
Variable Commands
There are at least three commands in Tcl 8.5+ named
variable. They are:
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.
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.
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!
RZ or have a look on
TclOO private variables See Also edit