帧和执行级别之间有什么区别?
我写了一个小例子来找出答案.我意识到每次调用proc时级别编号都会增加.
另一方面,帧编号每次递增
出于这个原因,我开始将层次视为帧的子集.现在我正在调试一些现实代码,我意识到级别数可以增加,而帧数也不会增加.如何理解这些东西?
堆栈级别,这是info level重要的,因为它们是你可以使用upvar和uplevel访问的.这意味着Tcl"堆栈" 实际上是一棵树,因为您可以使用uplevel上升到更高的级别并启动一个新的分支,通过调用过程(或类似过程的事物)来更深入地执行每一步或者打电话给namespace eval; 该info level命令真正谈到当前分支一直追溯到根目录.
该info frame命令以不同的方式遍历框架树 - 我认为它使用它们堆叠的实际方式,框架能够出现两次 - 并报告关于每个框架的非常不同的信息.就个人而言,我只是发现它对调试很有用.
我们来试试一个简单的例子.这是一个互动会话.
% proc foo {y} {set x 1;bar $y $x $y}
% proc bar {a b args} {
puts [info level 0]
puts [info level -1]
puts [info frame 0]
puts [info frame -1]
}
% foo 3
bar 3 1 3
foo 3
type proc line 4 cmd {info frame 0} proc ::bar level 0
type proc line 1 cmd {bar $y $x $y} proc ::foo level 1
Run Code Online (Sandbox Code Playgroud)
好的,正如您所看到的,info level是报告使用的实际值并且不报告自身,而info frame报告该级别当前正在执行的操作.
这是一个更复杂的例子:
% proc foo {y} {set x 1;grill $y $x $y}
% proc grill {a b c} {uplevel 1 [list bar $a $b $c]}
% proc bar {args} {
for {set i 1} {$i<=[info level]} {incr i} {puts $i-->[info level $i]}
for {set i 1} {$i<=[info frame]} {incr i} {puts $i==>[info frame $i]}
}
% foo 3
1-->foo 3
2-->bar 3 1 3
1==>type eval line 1 cmd {foo 3} level 2
2==>type proc line 1 cmd {grill $y $x $y} proc ::foo level 1
3==>type proc line 1 cmd {uplevel 1 [list bar $a $b $c]} proc ::grill
4==>type eval line 1 cmd {bar 3 1 3} proc ::grill
5==>type proc line 3 cmd {info frame $i} proc ::bar level 0
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,info level 看不到的uplevel事情,但info frame 确实.但只能info level真正告诉你这些论点是什么.(请注意,如果你把一个文件,你的代码source,info frame报告甚至更多的信息.)