(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?
Michael
Hi Michael (of nstcl fame right?),
it's glad to see you in this list. I'm sure Gustaf or Uwe will have a better response for you but here's what I do:
AFAICS, static member variables are not supported as a language construct but you can either have a variable in the "Chapters" class, e.g.
Class Chapters
Chapters set current_chapter 12345
which can be fetched using [Chapters set current_chapter] from any other object or class or from an instance you can get/set the value as follows:
Chapters aChapter
[aChapter info class] set current_chapter 4567
puts [[aChapter info class] set current_chapter]
Now, suppose you have a Class instproc say printCurrentChapter:
Chapters instproc printCurrentChapter {} {
puts [[my info class] set current_chapter] }
aChapter printCurrentChapter
I hope that helps.
Best wishes, Neophytos
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?
Michael
Xotcl mailing list - Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
On Wed, 16 Apr 2003, Neophytos Demetriou wrote:
Hi Michael (of nstcl fame right?),
AFAICS, static member variables are not supported as a language construct but you can either have a variable in the "Chapters" class, e.g.
Class Chapters
Chapters set current_chapter 12345
In addition to this you can also use instvar to use a variable from another object, like:
Class Foo Foo set front 242
Foo instproc init {} { [self class] instvar front
puts $front }
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; } } =======================================================
On Wed, 16 Apr 2003, Gustaf Neumann wrote:
Most of the important things were already answered by Neophytos and Kristoffer.
Thanks to all of you for the pointers. XOTcl seems to be much more Tcl-ish than, say, [incr Tcl].
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.
This is a very helpful explanation. A light bulb just went on in my mind. Thanks.
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....
Very interesting. But, I'm confused by the results I'm seeing (both before & after applying the patch). It seems that even though [o1 test0] and [o1 test1] throw an error the variable is updated. And [o1 test3] does unset the variable.
% c1 show x=100 % c1 test 10 % c1 show x=10 % o1 test0 error: Can't find result of set x % c1 show x=13 % c1 test 10 % c1 show x=10 % o1 test1 error: can't set "x": private member x of ::c1 written from ::o1->test1 % c1 show x=13 % c1 test 10 % c1 show x=10 % o1 test2 error: can't read "x": private member x of ::c1 read from ::01->test2 % c1 show x=10 % o1 test3 % c1 show can't read "x": no such variable
I'm using XOTcl 1.0.2 (compiled from source) & Tcl 8.4.2 (.deb) on Linux.
(Neophytos: yes, I am the author of nstcl fame, though I didn't realize that would make me famous anywhere. :-)
Michael
can't read "x": no such variable
I'm using XOTcl 1.0.2 (compiled from source) & Tcl 8.4.2 (.deb) on Linux.
I had the same issue when I was experimenting with binding sql results into different variable names using traces. However, I haven't checked it out further but I suppose it could be handled by the unknown mechanism.
(Neophytos: yes, I am the author of nstcl fame, though I didn't realize that would make me famous anywhere. :-)
:) Still it is nice to see that you are considering xotcl ...
Best wishes, Neophytos
I'm not pretty sure about the goal of these examples yet, but - I'm guessing - it seems that the problem is that variable traces do not act like message interceptors. Instead they happen after the variable is affected. This simple -pure tcl- example illustrates that the var trace has no "protective" effect on x:
% proc a {var sub op} { error "I do not affect the variable" } % trace variable x rwu a % set x 3 can't set "x": I do not affect the variable % trace vdelete x rwu a % set x 3 %
Of course, one could reverse the effect, say with unset; but this is a bit cumbersome.
--uwe
On Wednesday 16 April 2003 22:35, Michael A. Cleverly wrote:
On Wed, 16 Apr 2003, Gustaf Neumann wrote:
Most of the important things were already answered by Neophytos and Kristoffer.
Thanks to all of you for the pointers. XOTcl seems to be much more Tcl-ish than, say, [incr Tcl].
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.
This is a very helpful explanation. A light bulb just went on in my mind. Thanks.
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....
Very interesting. But, I'm confused by the results I'm seeing (both before & after applying the patch). It seems that even though [o1 test0] and [o1 test1] throw an error the variable is updated. And [o1 test3] does unset the variable.
% c1 show x=100 % c1 test 10 % c1 show x=10 % o1 test0 error: Can't find result of set x % c1 show x=13 % c1 test 10 % c1 show x=10 % o1 test1 error: can't set "x": private member x of ::c1 written from ::o1->test1 % c1 show x=13 % c1 test 10 % c1 show x=10 % o1 test2 error: can't read "x": private member x of ::c1 read from ::01->test2 % c1 show x=10 % o1 test3 % c1 show can't read "x": no such variable
I'm using XOTcl 1.0.2 (compiled from source) & Tcl 8.4.2 (.deb) on Linux.
(Neophytos: yes, I am the author of nstcl fame, though I didn't realize that would make me famous anywhere. :-)
Michael
Xotcl mailing list - Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
On Wednesday 16 April 2003 22:35, Michael A. Cleverly wrote:
Very interesting. But, I'm confused by the results I'm seeing (both before & after applying the patch). It seems that even though [o1 test0] and [o1 test1] throw an error the variable is updated.
This is the semantics of variable traces in tcl (the trace is called afted the fact). It is possible to keep shadow-values of the variable contents and to restore the variable after a write operation to the original content, but my feeling was that the purpose was rather trapping unwanted access than prohibiting it...
And [o1 test3] does unset the variable.
i mentioned that in the maybe cryptical sentence at the end of my last mail. the xotcl method unset uses the tcl c function Tcl_UnsetVar2. If unset triggers a trace, and the trace ends with an error, the error is not returned by the Tcl_UnsetVar2 command. This is different to the case of set, where Tcl_ObjSetVar2 returns the error.
I'll try to make a simple example and post it to c.l.t, let us see, what the community thinks...
best regards -gustaf
On Thu, 17 Apr 2003, Gustaf Neumann wrote:
This is the semantics of variable traces in tcl (the trace is called afted the fact). It is possible to keep shadow-values of the variable contents and to restore the variable after a write operation to the original content, but my feeling was that the purpose was rather trapping unwanted access than prohibiting it...
I understand now. Thanks. :-)
Michael