# Rubyの継続でフィボナッチ(継続の初歩) _published: 2008/10/24_ ![alt](http://b.hatena.ne.jp/entry/image/http://d.hatena.ne.jp/shunsuk/20081024/1224845696) Rubyには継続(continuation)という仕組みが用意されています。Scheme以外で継続が使われるケースは少ないと聞いたような気がしますが、せっかく用意されているので今さらながら使ってみます。 いい例が思いつかなかったのですが。こんなカンジで。 ```ruby value = callcc {|$c| 0 } #...(1) value = $c.call 1 if value == 0 #...(2) puts value #=> 1 ``` (1)のところの「世界」をグローバル変数$cに保存しつつ、0を返しています。そして、(2)のところで、(1)で保存した「世界」にジャンプします。(2)から(1)に戻るイメージなのですが、「戻る」という言葉はふさわしくありません。(1)の「世界」の続きを実行する。 `callcc()` は、ブロックの戻り値を返しますが、 `Continuation#call(args)` が呼び出されたときは `args` を返します。 - [class Continuation](http://www.ruby-lang.org/ja/man/html/Continuation.html) (1)ではブロックの戻り値0を返しています。(2)では、引数1が返ります。 ちょっと改造。 ```ruby value = callcc {|$c| 0 } value = $c.call value + 1 if value < 5 puts value #=> 5 ``` ジャンプする回数を増やしました。 例が悪いですね。。。 本題。継続を使ってフィボナッチ数列を出力します。 ```ruby def fib a, b = callcc {|$c| [0,1] } puts b $c.call b, a + b if b < 100 end fib ``` 上の例が解れば、やってることは同じなので難しくはないと思います。 callccはcall with current continuationを意味します。私はC言語には詳しくないのですが、C言語のsetjmp/longjmpと同じようなカンジだそうです。それで、継続を使うと何がウレシイのか?よく出てくるのは大域脱出ですね。ネストしたループから一気に外側まで脱出できます。