如何在TCL中从proc返回-code $ value

问题描述 投票:1回答:1

我必须使用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中的返回,但我也希望它继续他在proc Y中的工作并放入“Y-out”。我可以做吗 ?

return tcl proc
1个回答
2
投票

return命令在概念上引发了一个异常(类型为return,它对应于Tcl C API中的TCL_RETURN结果代码),该异常由过程捕获(严格地说,通过执行诸如callframe管理和参数编组之类的过程的hull),其中它运行使这做一些事情。在正常的return的情况下,它只是使程序返回该值,但是当提供-code选项时,它可以指示程序执行其他操作;这是在从Tcl调用堆栈弹出callframe之后完成的。

因为2TCL_RETURN结果代码的实际值,它意味着它告诉程序船体(即整个Z程序)表现得像是对return的简单调用,这就是puts "Y - out"没有被执行的原因;由于执行Z而处理了返回异常。 (FWIW,return -code 2非常罕见.return -code 1 / return -code error更常见,因为它是一种获取错误异常的方法,这很有用,因为堆栈跟踪只是由错误异常构建的。)

您可以使用catchtry覆盖此处理。使用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的问题在于很容易意外地丢失错误。

© www.soinside.com 2019 - 2024. All rights reserved.