2010-07-10
■ [ruby] Ruby 1.9と波ダッシュ問題に関するメモ
ややこしすぎるのでメモ
参考資料:
超参考書: 477414164X
- UnicodeにはWAVE DASH(U+301C)という文字がある(波ダッシュ)
- 波ダッシュは、「0時から6時」みたいなときに使われるアレ
- UnicodeにはFULLWIDTH TILDE(U+FF5E)という文字もある(全角チルダ)
- チルダは、ダイアクリティカルマーク*1の一種。スペイン語でnの上に付いたりするやつ
- 見た目はだいたい同じ
- フォントによっては、波打ち方が逆になってることもある
- Shift_JISで使われる符号化文字集合は、JIS X 0201*2とJIS X 0208(第一第二水準漢字)
- JIS X 0208の1区33点に、波ダッシュという文字がある
- JIS X 0208に全角チルダはない
- EUC-JPは、JIS X 0102・0208・0212(補助漢字)の文字を扱える
- …のだけど、0212(補助漢字)はソフトウェアによっては実装されてなかったりするらしい*3。
- JIS X 0212には「ダイアクリティカルマークとしてのチルダ」がある。おいおい、JIS X 0102に半角チルダと被ってんじゃねーか
おわかりいただけただろうか?(筆者はいただけてない)
図
irb-1.9で試行錯誤した結果を図にしてみる。
これを見ると、Ruby 1.9は基本的に波ダッシュ間で変換するが、Windows専用エンコーディングに関してはWindowsの流儀にならって全角チルダと変換するらしい。
(流儀っていうか歴史的経緯っぽいな。明確に間違いだとする説も)
矢印のない部分はUndefinedConversionError(例えば全角チルダをShift_JISに変換しようとするとか)。
ちなみにJIS X 0212のチルダがどうなるかというと、EUC-JPの"\x8f\xa2\xb7"は半角チルダ(ASCIIの)になる。ふーん。eucJP-msの場合は、波ダッシュと同様全角チルダになる。 CP51932は3バイトEUC非対応。
波ダッシュ問題
http://gihyo.jp/dev/serial/01/ruby/0004 には"WindowsのシフトJISをUnicodeへと変換する際には,必ずWindows-31Jを指定するようにしましょう"とある。なぜだろうか。
Mac OS XのターミナルではWAVE DASHもFULLWIDTH TILDEも表示できたが、WindowsのソフトではWAVE DASHが表示できなかったり、普通と逆に波打ってたりすることがあるらしい。
だからWindows上ではFULLWIDTH TILDEに変換した方が安全だよねーってことか。なるほどね。
(追記:iOSでも、http://favotter.net/status.php?id=18132572781 の波ダッシュがAeroReaderで文字化けしてた。WAVE DASHさん…)
マジコメ
どうしてもソースコードをSJISにしたいんです!というプロジェクトがあった場合にマジコメは「coding: shift_jis」とすべきか「coding: windows-31j」とすべきか。
文字列リテラル内に全角チルダがあって、それをUTF-8とかで出力する場合、shift_jisだとWAVE DASHが出る。windows-31jだとFULLWIDTH TILDEが出る。
MacやLinuxだとどっちも見れるみたいだから、Windowsのことを考えてwindows-31jにしとくのが無難か。
余談
ruby-1.9.1-p378 > dash.encode("euc-jpms").dump Encoding::ConverterNotFoundError: code converter not found (UTF-8 to euc-jpms)
エンコーディング名がまちがってる時にこのエラーが出ると「UTF-8からEUC-JPmsには変換できないのかー」と勘違いしてしまうので、force_encodingのように「ArgumentError: unknown encoding name」って出してほしいな(あとでRedmine)