call / cc的语义和Ruby中的“确保”
据我所知,到目前为止,Ruby是唯一支持call/cc
和try/catch/finally
(编写为begin/rescue/ensure/end
块)的主流语言。
我不熟悉Ruby,但我的直觉告诉我这两个可能存在冲突,因为call/cc
允许任意控制流并ensure
需要一些保证控制流(某些代码路径必须在预定义的情况下执行,即离开含有块)。
那么,语言中是否存在任何冲突? 如果是这样,在这种情况下语言的定义行为是什么? 特别是,如果在begin/ensure
块或ensure/end
块中使用call/cc
会发生什么? 如果在块包含ensure
子句后调用捕获的call/cc
怎么办?
在Ruby中你有callcc
, throw
/ catch
和raise
/ rescue
/ ensure
。
throw
终止块, ensure
开始执行:
catch(:done) { begin puts "before" throw :done puts "after" # will not be called ensure puts "ensure" end }
生产:
before ensure
callcc
终止块, ensure
跳过:
callcc { |cc| begin puts "before" cc.call puts "after" # will not be called ensure puts "ensure" # will not be called end }
生产:
before
将Continuation
对象存储在全局变量中的另一个示例:
begin puts "before" callcc { |cc| $cc = cc } puts "after" ensure puts "ensure" end $cc.call
生产:
before after ensure after ensure after ...