On Wednesday 16 April 2003 08:30, Michael A. Cleverly wrote:
(Disclaimer: I'm quite new to XOTcl & I have read the tutorial a couple times but maybe not enough. :-)
What's the XOTcl idiom/way for a static member variable (what snit, the only other OO Tcl package/extension I've used, would call a "type variable")?
Contrived example: if I had a "Chapters" class, I'd like to have a single variable, accessible by all instances of the class, that kept track of the "current" chapter. Suggestions?
Most of the important things were already answered by Neophytos and Kristoffer. XOTcl does not need a special construct, since every class is an object as well, and variables kept in a class are nothing special. Note that a programmer can decide what kind of class he is referring to: - the class which is the type of the object (via "my info class") - the current class, which is currently active (via "self class") The type variable you are refering to is the first one.
Often, when people start to use XOTcl, there come requests how to achieve private instance variables. These can be easily achived through variable traces. Maybe someone finds the following code helpful or interesting....
================================================================= Object instproc private {instvar args} { foreach var $args { my trace variable $var rwu [list [self] private_check] } uplevel "my instvar $args" } Object instproc private_check {var sub op} { if {[string compare [self] [self callingobject]]} { if {[string equal "" [self callingobject]]} { set context "global context" } else { set context [self callingobject]->[self callingproc] } array set paraphrase {w written r read u unset} error "private member $var of [self] $paraphrase($op) from $context" } } =================================================================
Using this two instprocs, private instvars of an object can be declared. This is not a perfect solution but works quite well.....
================================================================ Class C C instproc init {} { my private instvar x y set x 100 } C instproc test {} { my set x 10 } C instproc show {} { puts x=[my set x] }
### test cases ### C c1 c1 show c1 test c1 show Object o1 o1 proc test0 {} { if {[catch {c1 set x 13} msg]} { puts "error: $msg" }} o1 proc test1 {} { c1 instvar x; if {[catch {set x 13} msg]} { puts "error: $msg" }} o1 proc test2 {} { if {[catch {c1 set x} msg]} { puts "error: $msg" }} o1 proc test3 {} { if {[catch {c1 unset x} msg]} { puts "error: $msg" }} c1 show o1 test0 o1 test1 o1 test2 #o1 test3 c1 show c1 set y 20 =======================================================
If you want to use this test please apply the small patch below to allow correct error propagation through traces in XOTcl. There seems to be a small bug in the actual tcl-versions, since Tcl_UnsetVar2 (which is used by xotcl unset) does not seem to propergate errors correctly from var traces as well....
======================================================= --- xotcl.c~ Fri Mar 21 15:57:45 2003 +++ xotcl.c Wed Apr 16 19:00:35 2003 @@ -5978,7 +5978,7 @@ * "init"). */
if (!(obj->flags & XOTCL_INIT_CALLED)) { - int newargs, result; + int newargs; /* * Call the user-defined constructor 'init' */ @@ -6986,8 +6986,7 @@ Tcl_SetObjResult(in, result); return TCL_OK; } else { - return XOTclVarErrMsg(in, "Can't find result of set ", - ObjStr(objv[1]), 0); + return TCL_ERROR; } } =======================================================