如何知道当我获取 tcl 脚本时,哪个 proc/eval 在哪个文件和哪一行执行?
下面是我的代码:
set counts [info frame];
set frame_list [info frame [expr {$counts - 2}] ] ; #for cmd type is "eval"
set frame_list [info frame [expr {$counts - 1}] ] ; #for cmd type is other like "source"
[dict get $frame_list file] # to get file
[dict get $frame_list line] # to get line in file
但有时在脚本中文件中有内部eval,让frame_list获取错误级别信息。 如何让tcl得到正确的文件和线路?
我认为你想要
interp debug {} -frame true
,这(以巨大的性能成本)可以在更多情况下进行额外的计算来解析文件和帧的行号:
没有:
proc dothing script {
eval $script
}
proc foo {} {
dothing {
puts "In dothing: [info frame 0]"
}
}
foo
打印
In dothing: type eval line 2 cmd {info frame 0} proc ::dothing level 0
调试框架为真:
interp debug {} -frame true
proc dothing script {
eval $script
}
proc foo {} {
dothing {
puts "In dothing: [info frame 0]"
}
}
foo
打印
In dothing: type source line 9 file /home/cyan/git/research/tcl/frame/without.tcl cmd {info frame 0} proc ::dothing level 0
(Tcl 能够将
type eval
框架转换为报告中的 type source
框架,因为它具有来自 interp debug {} -frame true
的足够信息)。
但仍有很多情况无法做到这一点:
interp debug {} -frame true
proc dothing script {
eval $script
}
proc foo {} {
set s {
puts "In dothing: [info frame 0]"
}
dothing $s
}
foo
仍然打印
In dothing: type eval line 2 cmd {info frame 0} proc ::dothing level 0
这个例子(对包含源文件中定义的字符串文字的变量进行评估)可能可以在 Tcl 核心中通过足够的工作来解决(我有实验以这种方式将脚本跟踪回文字),但总会有是其他不可能的地方(比如正在运行的脚本是通过网络套接字接收的 - 它只是一个值,并且在文件中没有有源位置,或者是由其他代码动态构建的脚本)。因此,没有通用的方法可以始终获得
type source
框架报告。
另请注意,在插值上启用帧调试是一种单向操作 - 一旦启用,它将保持启用状态,无法再次将其关闭。因此,如果您正在从事性能很重要的事情,请注意性能受到的影响。
有时运行时根本不知道文件和行信息。对于任何生成的代码尤其如此;它只是不绑定回特定的源位置。 (还有其他情况也是如此,但我现在不记得它们了,除了处理加密代码时,这不是普通 Tcl 解释器中发生的事情。)
当你使用
info frame
时,你只需要注意很多按键不一定在那里。