2

据我所知,Ruby 是唯一同时支持call/cctry/catch/finally(写成begin/rescue/ensure/end块)的主流语言。

我不熟悉 Ruby,但我的直觉告诉我这两者可能存在冲突,因为call/cc允许任意控制流并ensure需要一些有保证的控制流(某些代码路径必须在预定义的情况下执行,即离开包含堵塞)。

那么,语言中是否存在任何冲突?如果是这样,在这种情况下,语言的定义行为是什么?特别是,如果call/ccbegin/ensure块或块中使用会发生什么ensure/end?如果call/cc在块包含ensure子句之后调用捕获怎么办?

4

1 回答 1

4

在 Ruby 中,您有callcc, throw/catchraise/ rescue/ ensure

throwensure用begin 执行终止块:

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

产生:

before
ensure

callccensure以跳过开始的方式终止块:

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
...
于 2013-06-11T12:38:54.087 回答