2010-12-29
Ruby 1.9 で日本語 (UTF-8 の文字列) を正しく表示させる方法
Windows 環境でコマンドプロンプトを使って日本語を表示させようとして躓いたのでメモ。ソースコードを UTF-8 で書きたい人を対象にしています。
環境
- Windows7
- コマンドプロンプトデフォルトのままでコードページ 932
- Ruby 1.9.2-p136
まとめ
先にまとめを書いておきます。
- ソースコードを UTF-8 (BOM 無し) で書く。
- ソースコードのエンコーディングを正しく判断できるように -*- encoding: utf-8 -*- をソースコードの先頭に書く
- ruby のオプションで -U を使うか、-Eexternal_encoding:internal_encoding を使う
- File.open する時は、デフォルトの外部エンコーディングで読みに行くので、オプションで適切なエンコーディングを指定する
- 例: File.open("test.txt", "r:EUC-JP:UTF-8")
- 外部・内部エンコーディングはデフォルトと同じなら指定する必要はありません。
ソースコード
以下のソースコードを使ってテストしてみます。ソースコードは encoding_test.rb として、UTF8 (BOM 無し) で保存しました。
# -*- encoding: utf-8 -*- # 外部エンコーディング p Encoding.default_external p $stdout.external_encoding # 内部エンコーディング p Encoding.default_internal p $stdout.internal_encoding str = "こんにちは世界" # 文字列のエンコーディング。ソースコードと同じになる。 p str.encoding # 文字列を表示 puts str
オプションなし
ruby encoding_test.rb
結果
#<Encoding:Windows-31J> nil nil nil #<Encoding:UTF-8> 縺薙s縺ォ縺。縺ッ荳也阜
文字化けしてしまいました。デフォルトの外部エンコーディングが Windows-31J になっていますが、内部エンコーディングと $stdout の外部エンコーディングが nil になってしまってます。文字列自体は UTF-8 であることが分かります。
オプション -E を使う
- Eexternal_encoding と指定します。デフォルトの外部エンコーディングを指定するオプションです。
ruby -EWindows-31J encoding_test.rb
結果
#<Encoding:Windows-31J> nil nil nil #<Encoding:UTF-8> 縺薙s縺ォ縺。縺ッ荳也阜
オプションなしと同じ結果になりました。
オプション -U を使う
- U はデフォルトの内部エンコーディングを UTF-8 にするオプションです
ruby -U encoding_test.rb
結果
#<Encoding:Windows-31J> #<Encoding:Windows-31J> #<Encoding:UTF-8> #<Encoding:UTF-8> #<Encoding:UTF-8> こんにちは世界
正しく表示できました。デフォルトの外部・内部エンコーディングだけでなく、$stdout の外部・内部エンコーディングに適切なエンコーディングが指定されています。
オプション -E で内部エンコーディングも指定する
-Eexternal_encoding:internal_encoding とすることで、デフォルトの外部・内部エンコーディングを指定できます。
ruby -EWindows-31J:UTF-8 encoding_test.rb
結果
#<Encoding:Windows-31J> #<Encoding:Windows-31J> #<Encoding:UTF-8> #<Encoding:UTF-8> #<Encoding:UTF-8> こんにちは世界
こちらも正しく表示できました。環境によって外部エンコーディングの指定を適切に書き換える必要があります。また、ソースコードのエンコーディングが UTF-8 でなければ内部エンコーディングの指定も書き換える必要があります。