据我所知,ruby是目前唯一同时支持call/cctry/catch/finally的主流语言(编写为begin/rescue/ensure/end块)。
我对ruby并不熟悉,但我的直觉告诉我,这两者之间存在潜在的冲突,因为call/cc允许任意控制流,ensure需要一些有保证的控制流(某些代码路径必须在预定义的情况下执行,即离开包含块)。
那么,语言中是否存在冲突?如果是这样,在这种情况下,语言的定义行为是什么?尤其是,如果call/cc用于begin/ensure块或ensure/end块,会发生什么?如果在块包含call/cc子句之后调用捕获的ensure怎么办?

最佳答案

在ruby中有callccthrow/catchraise/rescue/ensure
throw终止执行ensurebegin的块:

catch(:done) {
  begin
    puts "before"
    throw :done
    puts "after"  # will not be called
  ensure
    puts "ensure"
  end
}

生产:
before
ensure

callcc终止块并跳过ensurebegin:
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
...

07-24 14:28