有没有一种简单的方法可以在Tcl中展开堆栈?
我有这个奇怪的问题,我必须回到特定的堆栈框架,字面意思。我可以使用info
命令获取所有帧信息,但是为了实际到达特定帧,我将在每个过程中设置一些局部变量并相应地检查它们。我想知道是否有更简单的方法。
答案 0 :(得分:4)
如果您需要获取代码以进行非本地返回(即,跳过几个级别),则可以从8.5开始使用-level
选项执行此操作return
。见这个例子:
proc foo-a {} {
puts a-in
foo-b
puts a-out
}
proc foo-b {} {
puts b-in
foo-c
puts b-out
}
proc foo-c {} {
puts c-in
foo-d
puts c-out
}
proc foo-d {} {
puts d-in
bar
puts d-out
}
proc bar {} {
puts bar-in
return -level 3
puts bar-out
}
foo-a
这通过抛出一种特殊的异常来起作用;细节很隐蔽。或者,如果您有8.6或其脚本实现,也可以使用try
和throw
(请参阅Tcler's Wiki了解在讨论代码时使用的Tcl代码8.6)。
对于较旧的Tcl版本,最简单的机制是使用return -code 42
并将一些代码放在堆栈中以catch
自定义异常并确定它是否是神奇值(此处为42;这将是catch
)的结果,并做出适当的回应。这可能非常有效,但也很混乱。这就是8.5之后为您提供更易于使用的工具的原因。
答案 1 :(得分:3)
简短的回答是,您可能更愿意重新考虑您的设计。
更长的答案是,唯一可行的方法(我能想到)就是抛出错误并将其恢复到需要停止的水平。当然,除了在调用堆栈中一直检查变量的火焰值更低的方法。然而,使用控制流的错误是......糟糕的形式。
答案 2 :(得分:1)
如果你愿意成为最前沿的,那么coroutines(8.6中提供)可能会满足你的需求。
否则,您可能会尝试注意当您在那里时需要达到的例程级别(即,将全局变量设置为[info level]),然后在更深的proc中,[uplevel] ]到那个绝对堆栈帧。像
这样的东西proc need-to-be-here {} {
set ::myframe [info level]
deeper-calls
}
proc deepest-call {} {
uplevel #$::myframe {what I need to do}
}
(未测试的)