如何准确获取Tcl脚本中执行命令/eval的文件路径及行号?
获取Tcl脚本当前执行代码的文件路径及行号
你之前硬编码栈帧层级的方式,遇到内部eval这类动态调用时必然失效,正确方案是遍历调用栈帧,筛选出包含实际脚本文件信息的帧。
核心思路
Tcl的info frame返回的栈帧中,只有关联实际脚本文件、proc定义的帧才会包含file和line字段。我们从当前栈帧向上遍历,找到第一个带file字段的帧,就能拿到准确的文件路径和行号。
实现代码
proc get_current_script_location {} { set frame_count [info frame] # 跳过当前proc自身的帧(索引0),从上层帧开始遍历 for {set i 1} {$i < $frame_count} {incr i} { set frame [info frame $i] if {[dict exists $frame file]} { return [list [dict get $frame file] [dict get $frame line]] } } # 交互式环境等无脚本文件场景返回空值 return [list "" ""] }
代码解释
- 遍历起始索引设为1:索引0是
get_current_script_location自身的栈帧,不是我们要找的目标执行代码帧 - 用
dict exists $frame file过滤:内部eval等动态执行的帧不会携带file字段,这样能精准定位到实际脚本中的代码位置 - 返回值为列表:第一个元素是文件路径,第二个是对应行号
验证示例
在demo.tcl中写入以下代码:
proc demo_inner_eval {} { eval { # 这里调用获取位置的proc set loc [get_current_script_location] puts "当前执行位置:文件=[lindex $loc 0],行号=[lindex $loc 1]" } } demo_inner_eval
执行source demo.tcl,会输出demo.tcl和eval代码块所在的行号,而非动态执行的虚拟行号。
内容的提问来源于stack exchange,提问作者JoshTitle
相关产品推荐
相关产品推荐

