Ruby の callcc(継続)
Ruby 2.2 から非推奨になってしまった callcc(継続)ですが…。
callcc は goto みたいなものです。
callcc {|cnt| ..}
とあるとき、継続 cnt が call されると、callcc {|cnt| ..}
の「後へ」処理が移ります。メソッド call に引数があった場合は、それが callcc {|cnt| ..}
の返り値になります。cnt は状態を保存していると同時に、ラベルみたいなものですね。なので、一度 callcc {} が出現しないともちろんそこへジャンプすることはできません。
なので、無限ループは簡単です。
c = nil callcc {|cnt| c = cnt} c.call
これで無限ループします。
ループから抜けます。
callcc do |cnt| n = 0 loop do puts n n += 1 cnt.call if n > 10 end end
メソッドからの脱出。
def a(cnt) puts "inner 1" cnt.call("jump") puts "inner 2" end puts callcc {|cnt| a(cnt)}
結果。
inner 1 jump
メソッド再帰からの脱出もできます。
def a(n, cnt) cnt.call(n) if n > 9 a(n + 1, cnt) end puts callcc {|cnt| a(0, cnt)} #=>10