Ruby 1.9.2.p0 で Array を print すると日本語が化ける
仕様のようでもあるし、バグのようでもある状態に遭遇したので書いてみる。
# -*- encoding: SJIS -*- arr = [] f = open( "sample.dat", "r:SJIS" ) while buf = f.gets arr.push $1 if buf =~ /あ(.+)$/ end f.close $\ = "\n" $, = "," print "1 ", arr print "2 ", arr.join print "3 ", arr.join($,) p arr
こんなプログラムを Windows のメモ帳で書いて sample.rb としておき、
あいうえお あきくけこ あしすせそ たちつてと なにぬねの
こんなファイルをメモ帳で書いて sample.dat という名前でセーブしといて、Windows7 + ruby-1.9.2-p0-x64-mswin64_80 で sample.rb を実行すると、
> ruby sample1.rb 1 ,["\x{82A2}\x{82A4}\x{82A6}\x{82A8}", "\x{82AB}\x{82AD}\x{82AF}\x{82B1}", "\x{82B5}\x{82B7}\x{82B9}\x{82BB}"] 2 ,いうえお,きくけこ,しすせそ 3 ,いうえお,きくけこ,しすせそ ["\x{82A2}\x{82A4}\x{82A6}\x{82A8}", "\x{82AB}\x{82AD}\x{82AF}\x{82B1}", "\x{82B5}\x{82B7}\x{82B9}\x{82BB}"]
こんなふうに化けてしまう。最後の p が化けるのはまだしも、1. が化ける理由がよくわからない。プログラミング言語 Ruby リファレンスマニュアル の print を見ると、
文字列以外のオブジェクトが引数として与えられた場合には、 当該オブジェクトを to_s メソッドにより文字列に変換 してから出力します。
とあって、プログラミング言語 Ruby リファレンスマニュアル の to_s を見ると、
self.join($,) と同じです。
とあるから、
print arr print arr.join
この二つの print の結果は同じになるはずなのにならない。この症状に気がつくのにかなり時間かかった。p138 では直っているのかもしれないけどわからない。ちなみに arr.to_s でも化ける。ということは、to_s は join と等価じゃないってことだよね。もうちょっと調べてみるか。
うーん、http://doc.ruby-lang.org/ja/1.9.2/method/Array/i/join.htmlを見ても 1.9.2 で Array の仕様が変わったとも書いてないから、やっぱりバグ?
とかいってたら,なんかある暇っぽい人から,
encoding:Windows-31J にして r:SJIS を r だけにしたらいいんじゃね?
という指摘があった.試してみたら確かに化けなくなった.encoding:cp932 でもいいらしい.
SJIS という表記がよくないという話はあるだろうけど,それにしても coding:SJIS で Windows-31J が読めて途中の処理はできているのに,print arr と print arr.join の処理結果だけ異なるというのはなぞ.