Tcl 打印过程参数时遇到问题

Tcl 打印过程参数时遇到问题,tcl,Tcl,我正在尝试创建一个proc跟踪方法。意味着当脚本将使用任何过程时,它将打印其过程名称并继续。为此,我采用了这种方法 rename proc _proc _proc proc {nm params body} { eval "_proc $nm \{$params\} \{ puts \"Enter proc $nm\"; puts \"Parameters: $params and body \" ; $body; puts \"Exit proc

我正在尝试创建一个proc跟踪方法。意味着当脚本将使用任何过程时,它将打印其过程名称并继续。为此,我采用了这种方法

rename proc _proc

_proc proc {nm params body}  { 
    eval "_proc $nm \{$params\} \{ 
    puts \"Enter proc $nm\";
    puts \"Parameters: $params and body \" ;
    $body;
    puts \"Exit proc $nm\"\}"
}

proc abc { param1 param2 param3 } {
    puts "$param1 and $param2 and $param3"
}
当我调用
proc abc
时,它以

Enter proc abc
Parameters:  param1 param2 param3  and body 
a and b and c
Exit proc abc

问:为什么这是打印体?我只想打印对我来说过于复杂的参数。让我们摆脱
eval
,减少初学者的报价量。(为了简单起见,省略其余代码。)

但那不是你想要的,是吗?您希望打印实际参数,而不是形式参数。这相当复杂

_proc proc {nm params body}  { 
    set cmd "[list puts "Enter proc $nm"];puts \"Parameters: "
    foreach p $params {
        append cmd "[lindex $p 0]=\$[lindex $p 0], "
    }
    append cmd " and body \";"
    _proc $nm $params $cmd$body\;[list puts "Exit proc $nm"]
}
但是,一旦您开始尝试从过程中返回有意义的结果,即使是这样,也会出现可怕的错误。虽然你可以用
捕获
返回
做一些可怕的事情来让它工作(在8.5中更容易,在8.6中更容易
尝试
最后
),但是你想要一种不同的方法。您需要执行跟踪

_proc proc {nm params body} {
    _proc $nm $params $body
    trace add execution $nm enter [list track_entry $nm $params]
    trace add execution $nm leave [list track_leave $nm]
}
_proc track_entry {nm params real args} {
    puts "Enter proc $nm"
    foreach formal $params actual [lrange $real 1 end] {
        append p " [lindex $formal 0]=$actual,"
    }
    puts "Parameters:$p and body"
}
_proc track_leave {nm args} {
    puts "Exit proc $nm"
}
如果我们尝试这样做,我们会看到我们得到了非常有用的输出,但我们不会“干扰”程序的工作:

% abc p d q Enter proc abc Parameters: param1=p, param2=d, param3=q, and body p and d and q Exit proc abc % info body abc puts "$param1 and $param2 and $param3" %abc p d q 输入proc abc 参数:param1=p、param2=d、param3=q和body p、d和q 退出程序abc %信息体abc 放置“$param1和$param2以及$param3”
有很多方法可以替代
proc
命令,允许注入跟踪和内省功能。但是,最好的方法可能是使用
命令将跟踪挂钩附加到过程,并让这些挂钩调用
命令来列出参数列表之类的内容,程序主体等。

你能给我提供一个链接,我可以在哪里得到这个info@Nitesh:如果将鼠标指针悬停在突出显示的单词“trace”和“info”上,您会发现它们是指向记录这些命令的页面的可单击链接。如果你访问并使用搜索框,你会发现更多关于它们的信息。谢谢你的回答。只是一个问题:在第行
\u proc track\u entry{nm params real args}
中你提到了3个参数(nm,param,real),但是在你调用
track\u entry的地方你传递了2个参数。如何?@Nitesh跟踪回调在调用时添加额外参数。
% abc p d q
Enter proc abc
Parameters: param1=p, param2=d, param3=q, and body
p and d and q
Exit proc abc
% info body abc

    puts "$param1 and $param2 and $param3"