问题
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).
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).
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?
回答1:
In Ruby you have callcc, throw / catch and raise / rescue / 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
}
produces:
before
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
}
produces:
before
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
produces:
before
after
ensure
after
ensure
after
...
来源:https://stackoverflow.com/questions/17036367/the-semantic-of-call-cc-and-ensure-in-ruby