跳回到不同的Tcl堆栈帧

时间:2012-04-04 23:40:14

标签: tcl

有没有一种简单的方法可以在Tcl中展开堆栈? 我有这个奇怪的问题,我必须回到特定的堆栈框架,字面意思。我可以使用info命令获取所有帧信息,但是为了实际到达特定帧,我将在每个过程中设置一些局部变量并相应地检查它们。我想知道是否有更简单的方法。

3 个答案:

答案 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或其脚本实现,也可以使用trythrow(请参阅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}
}

(未测试的)