RS routinely puts into Tk-provided scripts under development these two lines:
bind . <Escape> {exec wish $argv0 &; exit} catch {bind . <F1> {console show}} ;# Windows onlyWith an interactive console, the following shortcut is often helpful:
interp alias {} ? {} set errorInfoAnother little helper to display canvas x/y coordinates in the title bar:
bind .c <Motion> {wm title . %x/%y}
LES: Hmm... I have this:
frame $::w.wframe text $::w.wframe.textw scrollbar $::w.wframe.sbarThen I bind it:
bind $::w.wframe.textw <Motion> {wm title $::w "Position: %x/%y" }It works, but only so far as I move the mouse around the text widget. It won't work when I move it over the scroll or title bar. Certainly because I made a binding for the text widget only. Instead, I should bind the mouse movement to the frame, because it contains everything, right?
bind $::w.wframe <Motion> {wm title $::w "Position: %x/%y" }Wrong. Now it only works when I move the mouse over the scroll bar. But isn't the text widget contained in the frame too? What is wrong with my assumption?And I guess it is impossible to detect mouse movement over the title bar?
Robert Heller and tclguy explain how to use gdb constructively with Tcl-based applications in a clt thread [2].
LV 2007-09-25: Okay, here's a debugging situation that needs a technique. Hopefully it is obvious to readers that the small coherent example I provide here is merely to allow illustration of the type of problem, and that the real world examples of this are not so trivial. Thus, responses such as just read the code and look for the bug, while certainly a valid approach, may involve reading tens of thousands of lines of code, extensions, etc. and thus the location of this sort of problem could use a bit of help.Assume this small coherent example of tcl code:
proc novar {} { return $abc } proc a {} { return [novar] } proc b {} { return [a] }
% b can't read "abc": no such variableWhat would be useful here is some coding technique or trick that would change that simple error message into a stack trace that would get the developer looking into the appropriate proc.In an ideal situation, Tcl would just generate that stack trace by default.Lars H: I usually just type
set errorInfowhen I encounter this situation. That outputs the information you're asking for, does it not?LV I either didn't know that, or had forgotten that in my old age. Indeed, what I get if I remember is:
% b can't read "abc": no such variable % set errorInfo can't read "abc": no such variable while executing "return $abc" (procedure "novar" line 2) invoked from within "novar" (procedure "a" line 2) invoked from within "a" (procedure "b" line 2) invoked from within "b"Thanks!2007-09-26 UKo: And what's more: This really is an artificial example, cause in the real world you have these commands in a script and execute them with tclsh. And this gives you the full stack trace at once. So the default behaviour is just as you want it to be. Only in the really limited tclsh commandline you have to go the extra step of explicitly printing the stack trace.JH: As noted on the tkcon page, tkcon's hot errors functionality handles this for you graphically, going all the way to show you the source of the proc in a dig-down style.
Lars H: A useful procedure for use with trace is
proc putslist {args} {puts $args}since you can then go
trace add execution someProc {enter enterstep leave leavestep} putslist(or some subset of those operations) and get a raw dump of what someProc does. Unless the amount of trace data is large, it's more troublesome to format the trace data than it is to interpret this raw trace. It's also a bit troublesome for more ambitious tracing that the enter* and leave* operations have different syntaxes for the tracing command, hence the use of a catch-all args argument.