View · Search · Index
No registered users in community xowiki
in last 10 minutes

Re: [Xotcl] full trace support for XOTcl methods/procs

From: Gustaf Neumann <neumann_at_wu-wien.ac.at>
Date: Tue, 01 Jan 2008 19:26:08 +0100

Dear all,

first, a happy new year to everybody!

Eckhard Lehmann schrieb:
> Especially I look for a way to execute a proc before *every* statement
> inside an instproc. [trace] can do this via the "enterstep" and
> "leavestep" operators to [trace add execution]. Is this possible with
> filters and filterguards?

Here is a small example for tracing the calls within a method ("doit"),
which is somewhat similar to enterstep. Given is the following sample
script:

==========================
Class A
A instproc foo {} {
  my set f 2
}
A instproc doit {args} {
  my set a 3
}
Class B -superclass A
B instproc doit {args} {
  my set x 1
  my foo
  next
  my set y 4
}
B b1
==========================

for this script, we can define a filter, which uses call stack introspection
(self callingproc) to check, whether the current execution is within the
method "doit".

==========================
Class F
F instproc traceFilter args {
  if {[self callingproc] eq "doit"} {
    puts "Call: [self] [self calledproc] $args"
    set r [next]
    puts "Exit: [self] [self calledproc] $args => $r"
    return $r
  } else {
    next
  }
}
==========================

we add the method via mixin and register the filter to
to all instances of Class B and call the method,

==========================
B instmixin F
B instfilter {{traceFilter}}
b1 doit
==========================

The output is as follows:

Call: ::b1 set x 1
Exit: ::b1 set x 1 => 1
Call: ::b1 foo
Exit: ::b1 foo => 2
Call: ::b1 set a 3
Exit: ::b1 set a 3 => 3
Call: ::b1 set y 4
Exit: ::b1 set y 4 => 4

Note, that it just traces on the level of doit. This is not the same, what
tcl command traces provide (which is more of a debugging tool), but
filters are
in some respects more general: one can use traces as glueing code between
invocations, restrict the traces to certain objects or instances of classes,
one can stack multiple filters, or can provide different guard conditions
for different subclasses, etc.

tcl command traces just know about tcl-commands and nothing about
OO concepts, they allow to register other tcl commands to be executed
at certain checkpoints (e.g. one command before the invocation,
another command after invocation), but it does not provide e.g. means
to pass information between the before and after calls. that is much
easier with the "next" metapher in xotcl, which is uniform to all
other supported concepts.

i have not felt so far the need for tcl command traces, but i understand,
that for people used to it there is a change in the method-set and thinking
involved to move from command traces towards filters/mixins.

Allthough all xotcl methods are commands, with the current framework,
the tcl command traces are not called autmatically, since the basic
invocation mechanisms (with inheritance, filters, mixins) are handled
by xotcl. Without looking into the details, i think it should be possible
with moderate effort to incorporate tcl command traces in xotcl. But
one has to convince the developers, that adding yet another interception
mechanism to xotcl adds more benefits than causing confusion.

-gustaf neumann

PS: The example above can be implemented nicer of filterGuards,
but unfortuantely, there is a bug in the current release (most likely
since ever) within the evaluation of callstack introspection commands
from within a guard. This bug will be removed in the forthcoming
release, where one can write:

F instproc traceFilter args {
  puts "Call: [self] [self calledproc] $args"
  set r [next]
  puts "Exit: [self] [self calledproc] $args => $r"
  return $r
}

B instfilter {{traceFilter -guard {
  [self callingproc] eq "doit"
}}}