问题描述
到目前为止,我知道Ruby是唯一同时支持call/cc
和try/catch/finally
(写为begin/rescue/ensure/end
块)的主流语言.
As I know so far, Ruby is the only mainstream language that supports both call/cc
and try/catch/finally
(written as begin/rescue/ensure/end
block).
我不熟悉Ruby,但是我的直觉告诉我这两者之间可能存在冲突,因为call/cc
允许任意控制流,而ensure
则需要一定的控制流(某些代码路径必须在A中执行预定义的情况,即离开包含块).
I am not familiar with Ruby, but my intuitive tell me that there are potential conflicts of that two, since call/cc
allows arbitrarily control flow and ensure
require some guaranteed control flow (some code path MUST be executed in a pre-defined situation, namely leaving the containing block).
那么,该语言是否存在任何冲突?如果是这样,在这种情况下该语言的定义行为是什么?尤其是,如果在begin/ensure
块或ensure/end
块中使用call/cc
,会发生什么情况?如果在包含ensure
子句的块后调用捕获的call/cc
怎么办?
So, are there any conflicts exists in the language? if so what is the defined behavior of the language in such a case? Especially, what happen if call/cc
being used in a begin/ensure
block or in the ensure/end
block? What if calling a captured call/cc
after the block contains ensure
clause?
推荐答案
在Ruby中,您有 callcc
, throw
/ 和 raise
/rescue
/ensure
.
In Ruby you have callcc
, throw
/ catch
and raise
/ rescue
/ ensure
.
throw
通过开始执行ensure
终止该块:
throw
terminates the block with ensure
begin executed:
catch(:done) {
begin
puts "before"
throw :done
puts "after" # will not be called
ensure
puts "ensure"
end
}
产生:
before
ensure
callcc
以ensure
开始跳过来终止该块:
callcc
terminates the block with ensure
begin skipped:
callcc { |cc|
begin
puts "before"
cc.call
puts "after" # will not be called
ensure
puts "ensure" # will not be called
end
}
产生:
before
另一个将 Continuation
对象存储在全局变量中的示例:
Another example storing the Continuation
object inside a global variable:
begin
puts "before"
callcc { |cc| $cc = cc }
puts "after"
ensure
puts "ensure"
end
$cc.call
产生:
before
after
ensure
after
ensure
after
...
这篇关于呼叫/cc和“确保"的语义包括:在Ruby中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!