Version 14 of trace

Updated 2003-11-24 14:07:10

http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/trace.htm


What are some of the uses for trace? Well, see Traces for some wiki info.

  • Communication between parts of a GUI and the internal state of the app. (Simplified MVC, observer). In general communication between different parts of an app without coupling them strongly.
  • Simple constraint computation for a number of variables ("if this flag is on and that one is on, then no other is allowed to be set", and some such).
  • Canvas text items bound to a variable, dynamically updating

A small example to illustrate the order of processing -- JCW

  proc tellme {id a e op} {
    puts "  $id a=$a e=$e op=$op\
                ax=[info exists ::$a] ex=[info exists ::${a}($e)]"
  }

  proc do {args} {
    puts "<$args>"
    uplevel $args
  }

  trace var a wu {tellme array}
  trace var a(1) wu {tellme element}

  puts [trace vinfo a]
  puts [trace vinfo a(1)]

  do set a(0) zero
  do set a(1) one
  do set a(2) two
  do unset a(0)
  do unset a(2)
  do unset a

  # output is:
  #
  #   {wu {tellme array}}
  #   {wu {tellme element}}
  #   <set a(0) zero>
  #     array a=a e=0 op=w ax=1 ex=1
  #   <set a(1) one>
  #     array a=a e=1 op=w ax=1 ex=1
  #     element a=a e=1 op=w ax=1 ex=1
  #   <set a(2) two>
  #     array a=a e=2 op=w ax=1 ex=1
  #   <unset a(0)>
  #     array a=a e=0 op=u ax=1 ex=0
  #   <unset a(2)>
  #     array a=a e=2 op=u ax=1 ex=0
  #   <unset a>
  #     array a=a e= op=u ax=0 ex=0
  #     element a=a e=1 op=u ax=0 ex=0

On news:comp.lang.tcl , CLN answers Erik Leunissen's question: Erik Leunissen wrote:

 > The following passage from the man page to the trace command is
 > mystifying to me:
 > 
 > "If an unset occurs because of a procedure return, then the trace will
 > be invoked in the variable context of the procedure being returned to:
 > the stack frame of the returning procedure will no longer exist."
 > 
 > I've read it again and again; I can't imagine how a procedure return
 > affects/causes an unset.
 > ...


    proc foo { } { 
       set x 1
       trace variable u x {some code here}
    }

When foo is invoked, x is created (locally), has a trace associated with it, then becomes unset as foo exits.


On news:comp.lang.tcl , Kevin Kenny answers someone wanting to link a C variable and a Tcl variable, and have a Tcl proc invoked when the C code modified the variable:

 Look in the manual for Tcl_UpdateLinkedVar.  The Tcl engine has no way of
 telling that you've changed the variable in C; if you call Tcl_UpdateLinkedVar,
 that tells it your value has changed, and it fires the traces.

Simple file I/O in traces:

 trace var stdout w {puts stdout $stdout ;#}
 trace var stdin  r {gets stdin  stdin   ;#}

The variables are named like the file handles. Little demo, that waits for input and prints it capitalized:

 set stdout [string toupper $stdin]

Trace programming's hazardous--it too often presents mysteries to unfamiliar programmers.

Traces are like widgets and images in that they are resources that can be leaked and/or need clean-up. Counter-intuitive results sometimes arise because traces are additive rather than substitutive; a particular trace can fire a whole chain of commands. To wipe the global space clean of traces,

    foreach variable [info glob] {
        foreach pair [trace info variable ::$variable] {
            foreach {op traced_command} $pair {}
            set op [string range $op 0 0] 
            trace vdelete ::$variable $op $traced_command
        }
    }

"It's easy to constrain the depth of recursion by having the trace procedure look at [info level]." So observes KBK, in commenting on use of enterstep [L1 ]


Tcl syntax help

Arts and crafts of Tcl-Tk programming Category Command