From: SASADA Koichi Date: 2007-05-30T03:31:26+09:00 Subject: [ruby-dev:30834] Re: callcc, each and local val  ささだです。  この問題点に気付いてくれる方がいて大変喜んでいます。  まず、継続がキャプチャする対象ですが、1.9 の実装ではすべての ローカル変数を保存することで実現しています。1.8 では、継続では ローカル変数は保存していませんでした。  どうするべきなんでしょうか。継続は「こうでなければならない」 というのは、よくわかっていません。誰か、「〜だから〜であるべき だ」という話をしてもらえないでしょうか。  Scheme の場合ですと、 (let ((v #f)) (call/cc (lambda (c) (set! v #t) (c #t))) (print v)) ;=> #t となり、ローカル変数が変更されていることがわかります。1.8 以 前、および Scheme などとあわせるべきでしょうか。  実装レベルの話をすると、VMスタックを簡単にコピーするだけです ので、保存していないということです。  実は、自分も cont = nil callcc{|c| cont = c } cont.call というコードが動かず、少し悩んでしまいました。  ちょっと、実装方法がうまいこと思い浮かばなかったんですが、各 スコープで binding 相当をやるようにすれば出来るのかなぁ、とは 思います。 sheepman さんは書きました: > こんばんは、sheepman です。 > > trunk の callcc に関してです。 > Array#each のブロックの中で callcc を呼んだ時の、ローカル変数の > 参照がおかしいです。 > > $ cat t.rb > vv = 0 > $c = 0 > [1, 2, 3].each{|i| > callcc {|k| $k = k} > $c += 1 > vv += 1 > } > p [vv, $c] > $k.call if vv < 10 and $c < 10 > > $ ruby-1.8 -v t.rb > ruby 1.8.6 (2007-04-20 patchlevel 5000) [i686-linux] > [3, 3] > [4, 4] > [5, 5] > [6, 6] > [7, 7] > [8, 8] > [9, 9] > [10, 10] > > $ ruby-1.9 -v t.rb > ruby 1.9.0 (2007-05-29 patchlevel 0) [i686-linux] > [3, 3] > [3, 4] > [3, 5] > [3, 6] > [3, 7] > [3, 8] > [3, 9] > [3, 10] > -- // SASADA Koichi at atdot dot net