我必须使用proc Z,它返回的内容类似于“ return -code 2” $ something,但是我不知道它是如何工作的。
proc X {} {
puts "X - in"
Y
puts "X - out"
}
proc Y {} {
puts "Y - in"
Z
puts "Y - out"
}
proc Z {} {
puts "Z - in"
return -code 2 "some value"
puts "Z - out"
}
X
输出为:
X - in
Y - in
Z - in
X - out
我无法在proc Z中更改return,但我也希望它继续在proc Y中继续他的工作并放入“ Y-out”。我可以吗?
答案 0 :(得分:2)
从概念上讲,return
命令会引发一个异常(严格地,通过以下方式捕获)(类型为return
,它对应于Tcl C API中的TCL_RETURN
结果代码)过程外壳,它执行诸如调用框架管理和参数编组之类的操作),并在其中运行以使其执行某些操作。在普通return
的情况下,它只是使过程返回该值,但是当提供-code
选项时,它可以指示过程执行其他操作。这是在 从Tcl调用堆栈中弹出呼叫帧之后完成的。
因为2
是TCL_RETURN
结果代码的实际值,这意味着它告诉过程外壳(即整个Z
过程)的行为就像是对return
的简单调用,这就是为什么未执行puts "Y - out"
的原因; Z
的执行导致正在处理返回异常。 (FWIW,return -code 2
很少见。return -code 1
/ return -code error
更为常见,因为它是引发 error 异常的一种方式,之所以有用,是因为堆栈跟踪仅由错误异常构建。)
您可以使用catch
或try
覆盖此处理。使用try
来实现此目的要容易一些,因为catch
是一个相当广泛的基元。试试这个:
proc Y {} {
puts "Y - in"
try {
Z
} on return {msg} {
puts "Z told us to return '$msg'"
}
puts "Y - out"
}
如果您只是想在调用后编写一小段代码,但又不想干扰,那么try
…finally
是正确的方法:
proc Y {} {
puts "Y - in"
try {
Z
} finally {
puts "Y - out"
}
}
如果您使用的是Tcl 8.5(或更早版本),则不会有try
。这是catch
的版本:
proc Y {} {
puts "Y - in"
set code [catch {
Z
} msg]
if {$code == 2} {
puts "Z told us to return '$msg'"
}
puts "Y - out"
}
catch
的问题在于,很容易意外丢失错误。