今日やったRuby 1.9への移行方法
rcodetoolsがRuby 1.9に対応していなかったので、手許のバージョンで対応させておいた。そろそろリリースしないといけないな。
rct-completeコマンドはRubyのメソッド等を補完するプログラムなのだが、「Object#methods」などが文字列ではなくてSymbolを返すことの影響をもろに受けてしまった。たとえばmethが文字列だとして、「Kernel.instance_methods(false).include? meth」なんてコードを実行したらRuby 1.8では動いてもRuby 1.9では動かなくなってしまう。だから「Kernel.instance_methods(false).map{|x| x.to_s}.include? meth」のようにmapで文字列化しておく。これで互換性は保てる。「Enumerable#stringify」なんてのを定義してもよい。
module Enumerable def stringify map{|x| x.to_s} end end
さらに、StringがEnumerableではなくなったのが「ぎゃーーーー」ってレベルの大騒ぎだ。だから「alias :each :each_line」と「include Enumerable」しておく。もう定番かな?あと、Ruby 1.8であった「Enumerable#enum_with_index」がなくなってしまったので「Enumerable#each_with_index」の別名にしておいた。
Ruby 1.9ではブロックなしの「each_with_index」は「enum_with_index」と同じ働きをするからだ。
「Array#to_s」がinspectの挙動になっているので、強制的にjoinの別名にしておいた。
まとめるとこんな感じ。
if RUBY_VERSION >= "1.9" class String alias :each :each_line include Enumerable end module Enumerable alias :enum_with_index :each_with_index end class Array alias :to_s :join end end
Ruby 1.8用に書かれたスクリプトをRuby 1.9でも動くようにする「compat.rb」という移行支援スクリプトでも作ろうかな?