My question is: is it possible to trace variable of particular object? For example, I have 5 objects of the same class, and I need to check if particular variable in each object is changed and call particular procedure that is updated Tk widget that is corresponds to this particular object. I a little bit stuck because I know that we can add trace to global variable, but not sure how to trace variable inside particular object, especially if it could not exist until writing occurs. Thank you in advance, George.
-
1Maybe the TclOO trace filter could be of use to you? (I have not done this myself before, so... I can’t posit an actual answer.)Dúthomhas– Dúthomhas2024-08-22 16:02:23 +00:00Commented Aug 22, 2024 at 16:02
-
I found the way by direct access to object variable: trace add variable [info object namespace $obj]::objVariable write callbackProc, but it does not look like a good solutiongeorgtree– georgtree2024-08-22 16:12:26 +00:00Commented Aug 22, 2024 at 16:12
-
1If the object itself knows what widget it is associated with, then the TclOO trace filter would be a nicer solution (because you would only have to add the one trace method to work for all instances of the object), but glad you got it working.Dúthomhas– Dúthomhas2024-08-22 16:16:41 +00:00Commented Aug 22, 2024 at 16:16
-
Ok, my solution doesn't work right because I don't know to which objects this particular variable belongs...georgtree– georgtree2024-08-22 16:41:10 +00:00Commented Aug 22, 2024 at 16:41
-
You have to know at some point in the code — the best time is when the object is either created or when it is associated with the widget (presumably both those things happen at the same time?). Or am I misunderstanding you?Dúthomhas– Dúthomhas2024-08-22 16:44:40 +00:00Commented Aug 22, 2024 at 16:44
|
Show 1 more comment
1 Answer
The varname standard method (normally not exported, so typically only usable via my) should give you something you can use with trace or a Tk widget.
oo::class create Example {
variable xyz
constructor {script} {
trace add variable [my varname xyz] write $script
}
method test {} {
set xyz 123
}
}
Example create eg {apply {args {
puts "Foo: $args"
}}}
eg test
Note that in this specific case, you don't need varname because the trace resolves the variable name using local rules. But you would if you were using vwait or a Tk widget.
A common related case is when you want to get the trace to call a (non-exported) method of the object. In that case, you make the trace callback with something like this:
trace add variable $varName write [namespace code {my CallbackMethod}]
Tcl 8.7/9.0 has a callback command to make that easier.
trace add variable $varName write [callback CallbackMethod]
2 Comments
georgtree
Got it, thank you! Another small question - is it possible to trace method execution with trace add execution command? Thank you
Donal Fellows
Not directly; methods aren't commands (different C signatures). On the other hand, you can use a
filter to get the information that enter and leave events provide (and do more). Perhaps the trace mechanisms ought to be extended, but that's full feature request territory.