Ruby 1.8.x対応を見送った
私がRubyで書いているLisp方言、 [Nendo]について。
[Nendo]でmapをネストして2重ループを形成すると変な動作をする。何だこれは。
クロージャのレキシカル変数の内容がどんどん破壊される。
小一時間ほど追いかけた結果、Ruby 1.8.xのクロージャの問題だということが発覚した。
結論としては、Ruby 1.8.xのクロージャはレキシカルクロージャではないことを自分が忘れていたのが問題。…
[Nendo]のlambdaはRubyのクロージャにそのままマッピングするようになっているため、Rubyのクロージャがレキシカルクロージャでない限り[Nendo]のlambdaが正常に動かないのも当然だった。
ちょっとテストとしてはわかりにくいかも知れないが、こんなRubyコードで実験した。
#!/usr/local/bin/ruby
lambda1 = lambda { |val|
printf( "(0) = %s\n", val )
val = 'A'
printf( "(1) = %s\n", val )
lambda2 = lambda { |val|
printf( "(2) = %s\n", val )
}
lambda2.call( 'B' )
printf( "(3) = %s\n", val )
val
}
lambda1.call( 'START' )
- Ruby 1.9.2devでは期待通り
$ ruby --version ruby 1.9.2dev (2009-07-18 trunk 24186) *powerpc-darwin9.5.0* $ ./t.rb (0) = START (1) = A (2) = B (3) = A
(3)の箇所で値 ‘A’ が保持されている
- Ruby 1.8.7では…
bash-3.2$ ruby --version ruby 1.8.7 (2009-06-12 patchlevel 174) *powerpc-darwin9.5.0* bash-3.2$ ./t.rb (0) = START (1) = A (2) = B (3) = B
(3)の箇所で値 ‘B’ になる。
Ruby 1.9.2がもうすぐ正式に出る時期なので、まじめにRuby 1.8.xでも動く様にするのはあきらめよう。 ちなみに、JRubyとかはどっちなんだろう。今度確認しよう。