Rig includes some features to help with debugging:
- Chk: - assertion checking
- Log: - logging information
- Tag: - tagged tracepoints
- bgerror - background error reporting
These are defined as global procs, and one of the very few exceptions to the rule that Rig does not affect the global namespace. One reason is that each of these may get called in many places. Another reason is that it's very simple to override or disable any of them.
Chk: {condition}
Evaluates the condition in the caller's context, and logs a message if false. That message will include a subst'ed version of the condition. Some examples:
set a 1 Chk: {$a == 2} => message will include the text "1 == 2" Chk: {[set a] == 2} => same text, i.e. "1 == 2"
The reason for this is that it lets you see what the value is which failed to satisfy the condition. There are however some limitations with this approach:
- a condition may be evaluated twice, it must not have side-effects
- failed conditions of the form "... && ..." will subst both sides of the &&
By default, Chk: is defined as an alias for "Rig check" using Tcl's auto_index mechanism for unknown commands. To override this, simply define Chk: yourself.
To disable all checks, define Chk: as follows at the start of the application:
proc Chk: {args} {}
This specific format using "args" even though Chk: always expects a single arg is special because the Tcl bytecode compiler will completely optimize it away.
Log: {info}
The argument must be braced and will be subst'ed in the callers context, so any embedded variable references and calls will be evaluated before being displayed. The result is sent to stdout, prefixed by a millisecond-resolution timestamp:
set a 123 Log: {a is $a} => this prints something like "13:10:31.534 a is 123"
The Rig module does not call Log: itself, but uses tclLog in a few places, which is defined in Tcl's init.tcl code. To override this to also call Log:, add this in the application startup code before loading the Rig module:
proc tclLog {msg} { Log: {$msg} }
By default, Log: is defined as an alias for "Rig log" using Tcl's auto_index mechanism for unknown commands. To override this, simply define Log: yourself.
To disable all logging, define Log: as follows at the start of the application:
proc Log: {args} {}
This specific format using "args" even though Log: always expects a single arg is special because the Tcl bytecode compiler will completely optimize it away.
Tag: ...
This is a utility to log program flow and variable values. The arguments to Tag: are either variable names or arbitrary text to be subst'ed (same as in Log:). Some examples:
set a 42 Tag: => logs only the location of the call Tag: a => adds "a: 42" to the output Tag: b => adds "b" as is, since it is not a variable name Tag: a a => adds "a: 42 a: 42" to the output Tag: {a a} => adds "a a" as is, since it is not a variable name Tag: {a is $a} => adds "a is 42" to the output Tag: {$a} => adds the text "42" to the output
By default, all Tag: output is disabled. It can be enabled either per module or per proc. If the above is used in a proc called "bar" in the module "foo", then
Rig tracepoint log foo => enables all tag output in the "foo" module Rig tracepoint log foo(bar) => only enables tag output for "foo bar" calls
The action taken in this case is "log", i.e. to log the results via "tclLog". Support for additional action types will be added in future Rig versions.
By default, Tag: is defined as an alias for "Rig tag" using Tcl's auto_index mechanism for unknown commands. To override this, simply define Tag: yourself.
To disable all tagging, define Tag: as follows at the start of the application:
proc Tag: {args} {}
Calls with such a definition will be completely optimized away by Tcl.
bgerror "msg"
This is the standard Tcl mechanism for reporting errors which occur in an event context, i.e. while in a vwait. Rig provides a default version for this, which uses tclLog to print the message as well as the current value of $::errorInfo.
By default, bgerror is defined as alias for "Rig bgerr" using Tcl's auto_index mechanism for unknown commands. To override it, simply define bgerror yourself.