TCL 命令包装

TCL command wrapping

我正在尝试编写一个 TCL proc,它允许我包装语句然后在内部 'execute' 它们。

例如,如果我原来有:

set var $tmp

我想要一些程序:

proc wrapper {command} {
   puts "do something here"
   puts $command #ie below : write "set var $tmp" to stdout
   EXECUTE COMMAND HERE
   puts "do something else here"
}

set void [wrapper {set var $tmp}]

我的动机是尝试为个人陈述编写自己的 timing/profiler。

如果您的唯一目的是获取一组代码执行所花费的时间,您可以尝试使用 time 命令,该命令已在 Tcl 中可用。

time script ?count?

此命令将调用 Tcl 解释器 count 次来评估脚本(如果未指定 count 则调用一次)。然后它将 return 一个形式为

的字符串
503.2 microseconds per iteration

表示每次迭代所需的平均时间量,以微秒为单位。时间是以经过的时间来衡量的,而不是 CPU 时间。

示例:

set code_block {
    foreach x "1 2 3" {
        set y [expr {$x*20}];
    }
}

puts [time $code_block 10]; # Executing the code for 10 times

这可能会产生随机输出,例如

11.9 microseconds per iteration

更新 1:

如果你想在执行的同时打印命令也是可以的。您可以使用 rename 命令覆盖 time 命令。

rename time _time; # Changing the 'time' to '_time'
# Defining your own 'time' command
proc time {command {count 1}} {
    # Printing the commands here
    puts $command
    # Calling the actual '_time' command
    # and returning that value from here
    return [_time $command $count]
}

将上面的代码放在代码的顶部,然后使用 time 命令将仅使用我们的自定义程序。

它们作为一组命令传递,而这又是一个字符串。但是,在评估代码时,它的行为就像它在 tclsh.

中的工作方式一样

正如Mr.Peter的回答,如果你的代码涉及到访问上一级命令、变量,那么你必须根据需要使用uplevelupvar

参考: time, rename

而不是"EXECUTE COMMAND",使用

uplevel 1 $command

请注意,如果您尝试使用 wrapper 之类的命令对脚本计时,它将不会进行字节编译,这意味着它不会像在过程中那样执行。

文档:uplevel