有没有简单的方法在Tcl中展开堆栈? 我有这个奇怪的问题,我必须回到特定的堆栈框架,从字面上。我可以使用info
命令获取所有帧信息,但要真正到达特定帧,我必须在每个过程中设置一些局部变量并相应地检查它们。我想知道是否有更简单的方法。跳回不同的Tcl堆栈框架
回答
如果你需要得到代码做一个非本地回报(即跳过后面几个级别),你可以从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
(有关讨论8.6中的代码时使用的Tcl代码,请参阅Tcler's Wiki)。
对于旧的Tcl版本,最简单的机制是使用return -code 42
,并将一些代码放在最上层到catch
自定义异常,并确定它是否为魔术值(42这里;它将是catch
)并做出适当回应。这可能相当有效,但也很麻烦。这就是为什么8.5以后会为您提供易于使用的工具的原因。
简短的回答是,你可能会更好地重新考虑你的设计。
较长的答案是,唯一真正的方法(我能想到)做到这一点是抛出一个错误,并在需要停止它的级别捕获它。当然,除了在调用堆栈中检查变量的方式之外,还有一些不太有用的方法。然而,使用控制流的错误是......糟糕的形式。
如果你愿意成为先锋,协程(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}
}
(未经测试)
邪恶使用'uplevel'+1。只是不要在任何我必须维护的代码中使用它! :-) – 2012-04-06 06:12:07
- 1. SIGABRT“在堆栈不够框架”
- 2. 如何在不同的堆栈框架中定位Perl变量?
- 3. JNI CallObjectMethod拧紧堆栈框架?
- 4. 它是一个堆栈框架吗?
- 5. Prolog跳出全球堆栈
- 6. 去 - 返回堆栈
- 7. 的Android添加新的/不同的片段返回堆栈
- 8. 堆栈溢出Web架构
- 9. 堆栈设计中的不同层
- 10. Java和不同类型的堆栈
- 11. 有许多不同类型的堆栈
- 12. 堆栈中的PHP回声?
- 13. 堆栈或堆栈分配不正确
- 14. 如何从异常“跳”到堆栈帧?
- 15. Xamarin - 返回堆栈不清除
- 16. 评估应用程序堆栈或框架的测试
- 17. GeddyJs(框架的NodeJS)部署到Heroku上雪松堆栈崩溃
- 18. 基于组件的完整堆栈框架?
- 19. 玩! - 期望方法控制器中的堆栈映射框架
- 20. 我制作的这个堆栈框架是否正确?
- 21. 平原MEAN堆栈或像mean.io一样的MEAN框架?
- 22. meego和android堆栈有何不同?
- 23. 堆栈不同变量上图
- 24. 文本框堆栈Angularjs
- 25. 调用堆栈和堆栈帧具有不同位置的平台?
- 26. 用于货架堆栈的伪代码
- 27. Android片段返回堆栈
- 28. 回文使用堆栈
- 29. 在加载的模块中找不到目前的堆栈框架
- 30. JVM - 堆栈和堆栈
用于调试或...? – 2012-04-04 23:43:34
用于跑步。我需要从一个程序到另一个程序。 – ilya1725 2012-04-04 23:49:49
虽然我认为Donal Fellows的答案是完美的,但是这个主题应该更好地转述,因为“展开堆栈”是一个与大多数程序员头脑中的异常处理/调试密切相关的术语。有关如何合理地改述的想法? – kostix 2012-04-05 14:18:33