据我所知,ruby是目前唯一同时支持call/cc
和try/catch/finally
的主流语言(编写为begin/rescue/ensure/end
块)。
我对ruby并不熟悉,但我的直觉告诉我,这两者之间存在潜在的冲突,因为call/cc
允许任意控制流,ensure
需要一些有保证的控制流(某些代码路径必须在预定义的情况下执行,即离开包含块)。
那么,语言中是否存在冲突?如果是这样,在这种情况下,语言的定义行为是什么?尤其是,如果call/cc
用于begin/ensure
块或ensure/end
块,会发生什么?如果在块包含call/cc
子句之后调用捕获的ensure
怎么办?
最佳答案
在ruby中有callcc
,throw
/catch
和raise
/rescue
/ensure
。throw
终止执行ensure
begin的块:
catch(:done) {
begin
puts "before"
throw :done
puts "after" # will not be called
ensure
puts "ensure"
end
}
生产:
before
ensure
callcc
终止块并跳过ensure
begin: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
...