2

私がこれまでに知っているように、Ruby は(ブロックとして記述された)call/ccとの両方をサポートする唯一の主流言語です。try/catch/finallybegin/rescue/ensure/end

私はRubyに精通していませんが、直感的に、call/cc任意の制御フローを許可しensure、保証された制御フローを必要とするため、その2つの潜在的な競合があることを教えてくれます(一部のコードパスは、事前に定義された状況で実行する必要があります。ブロック)。

それで、言語に矛盾はありますか?もしそうなら、そのような場合の言語の定義された動作は何ですか? 特に、ブロックやブロックcall/ccで使用されている場合はどうなりますか? ブロックの contains句の後にキャプチャを呼び出すとどうなりますか?begin/ensureensure/endcall/ccensure

4

1 に答える 1

4

Rubycallccでは、throw/catchraise/ rescue/がありensureます。

throwensurebegin を実行してブロックを終了します。

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

生成:

before
ensure

callccensurebegin をスキップしてブロックを終了します。

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 に答える