如何检测 Tcl 协程的完成?
How to detect the completion of a Tcl coroutine?
我想在 Tcl 中找到一种检测协程结束的好方法。考虑:
coroutine cor apply {{} {
yield 1
yield 2
yield 3
}}
try {
puts [cor]
puts [cor]
puts [cor]
puts [cor]
} trap {TCL LOOKUP COMMAND cor} {e} {
puts "done"
}
这行得通,但感觉像是一个 hack,而且很脆弱。如果我重命名 cor
并忘记在陷阱中重命名它,它将失败。如果我在陷阱中遗漏 cor
,它会捕获不相关的拼写错误。
必须有更好的方法。这是什么?
要检测命令是否仍然存在,请使用 info commands
并检查列表的长度 returns。 (我假设您可以保证命令名称中没有 glob 字符;如果这是真的,那么检查的成本非常低。)
while {[llength [info commands cor]]} {
puts [cor]
}
但是,如果您打算让协程作为生成器工作并且只在循环中使用,您可以让它直接发出信号表示它已完成。要做到这一点,让它产生一个 break
.
coroutine cor apply {{} {
yield [info coroutine]; # A sensible result from [coroutine]
yield 1
yield 2
yield 3
return -code break
# [tailcall break] would also work
}}
while true {
puts [cor]
}
诀窍是你不 yield
休息;您将其用作协程的最终结果。 (您的旧协程使用 yield
的结果,可能主要是运气。)
在写这篇文章时,我注意到了一个错误。循环到 运行 协程在 8.6.8 的顶层不起作用(我检查过的唯一版本)。不知道为什么。在 procedure/apply
上下文中很好(将协程名称作为参数传递是很自然的):
apply {c {
while true {
puts [$c]
}
}} cor
运行ning 的这些不同方式的字节码看起来并没有明显的不同。强制解释也可以使事情正常进行,这是一个很好表明这是一个真正的错误的迹象。
set while while
$while true {
puts [cor]
}
我想在 Tcl 中找到一种检测协程结束的好方法。考虑:
coroutine cor apply {{} {
yield 1
yield 2
yield 3
}}
try {
puts [cor]
puts [cor]
puts [cor]
puts [cor]
} trap {TCL LOOKUP COMMAND cor} {e} {
puts "done"
}
这行得通,但感觉像是一个 hack,而且很脆弱。如果我重命名 cor
并忘记在陷阱中重命名它,它将失败。如果我在陷阱中遗漏 cor
,它会捕获不相关的拼写错误。
必须有更好的方法。这是什么?
要检测命令是否仍然存在,请使用 info commands
并检查列表的长度 returns。 (我假设您可以保证命令名称中没有 glob 字符;如果这是真的,那么检查的成本非常低。)
while {[llength [info commands cor]]} {
puts [cor]
}
但是,如果您打算让协程作为生成器工作并且只在循环中使用,您可以让它直接发出信号表示它已完成。要做到这一点,让它产生一个 break
.
coroutine cor apply {{} {
yield [info coroutine]; # A sensible result from [coroutine]
yield 1
yield 2
yield 3
return -code break
# [tailcall break] would also work
}}
while true {
puts [cor]
}
诀窍是你不 yield
休息;您将其用作协程的最终结果。 (您的旧协程使用 yield
的结果,可能主要是运气。)
在写这篇文章时,我注意到了一个错误。循环到 运行 协程在 8.6.8 的顶层不起作用(我检查过的唯一版本)。不知道为什么。在 procedure/apply
上下文中很好(将协程名称作为参数传递是很自然的):
apply {c {
while true {
puts [$c]
}
}} cor
运行ning 的这些不同方式的字节码看起来并没有明显的不同。强制解释也可以使事情正常进行,这是一个很好表明这是一个真正的错误的迹象。
set while while
$while true {
puts [cor]
}