工作原理 return -TCL 中 proc 的代码 $value
How works return -code $value from the proc in TCL
我必须使用 proc Z,它 return 类似于 "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"。我可以吗?
return
命令在概念上引发异常(类型 return
,对应于 Tcl C API 中的 TCL_RETURN
结果代码)被捕获它运行的过程(严格来说,通过执行诸如调用框架管理和参数编组之类的过程外壳)以使其执行某些操作。在正常 return
的情况下,它只是使过程 return 该值,但是当提供 -code
选项时,它可以指示过程做其他事情;这是在 调用帧从 Tcl 调用堆栈中弹出后完成的。
因为 2
是 TCL_RETURN
结果代码的实际值,这意味着它告诉程序外壳(即整个 Z
程序)表现得像它是对 return
的简单调用,这就是 puts "Y - out"
未被执行的原因;由于 Z
的执行,正在处理 return 异常。 (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
的问题是很容易一不小心就丢错了
我必须使用 proc Z,它 return 类似于 "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"。我可以吗?
return
命令在概念上引发异常(类型 return
,对应于 Tcl C API 中的 TCL_RETURN
结果代码)被捕获它运行的过程(严格来说,通过执行诸如调用框架管理和参数编组之类的过程外壳)以使其执行某些操作。在正常 return
的情况下,它只是使过程 return 该值,但是当提供 -code
选项时,它可以指示过程做其他事情;这是在 调用帧从 Tcl 调用堆栈中弹出后完成的。
因为 2
是 TCL_RETURN
结果代码的实际值,这意味着它告诉程序外壳(即整个 Z
程序)表现得像它是对 return
的简单调用,这就是 puts "Y - out"
未被执行的原因;由于 Z
的执行,正在处理 return 异常。 (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
的问题是很容易一不小心就丢错了