本文介绍了呼叫/cc和“确保"的语义包括:在Ruby中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我知道Ruby是唯一同时支持call/cctry/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


callccensure开始跳过来终止该块:


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中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 11:40