Ruby 1.9.1のm17nについてメモ
2009/2/8追記: 今はもう↓の公式ドキュメントやid:macksさんのドキュメントなどいろんな情報が出ているので、このメモの存在意義は微妙ですが、一応1.9.1に合わせて修正しておきました。
この辺のドキュメントが見つからず(まだない?)、いろいろ試行錯誤して分かったことをメモ。
まず、Ruby 1.9では文字列オブジェクトがそれぞれ文字コードを持っている。
p "a".encoding #=> #<Encoding:US-ASCII>
ファイルの先頭に
# -*- encoding: UTF-8 -*-
と書いておくと、文字列リテラルのencodingがUTF-8になる。
p "あ".encoding #=> #<Encoding:UTF-8> p "a".encoding #=> #<Encoding:UTF-8>
これを書かずに文字列リテラルに日本語を書くとinvalid multibyte charというエラーになる(デフォルトはUS-ASCIIなので)。
[]とかのメソッドは文字単位に。
p "あいう"[0] #=> "あ" p "あいう".size #=> 3
文字コード変換。
p "あ".encode("EUC-JP")
同じバイト列のままencodingを変更するにはforce_encoding。破壊的なメソッド*1なので注意。
p "\xE3\x81\x82".force_encoding("UTF-8") #=> "あ"
普通にファイルを読み込むと、encodingはEncoding.default_external(デフォルトでは、環境変数LANGなどから推定された実行環境の文字コード)になる。
open("test.txt") do |f| p f.external_encoding #=> #<Encoding:Windows-31J> p f.internal_encoding #=> nil p f.gets().encoding #=> #<Encoding:Windows-31J> end
open("test.txt", "r:utf-8") do |f| p f.external_encoding #=> #<Encoding:UTF-8> p f.internal_encoding #=> nil p f.gets().encoding #=> #<Encoding:UTF-8> end
Shift JISのファイルをUTF-8に変換して読み込む。
open("test.txt", "r:windows-31j:utf-8") do |f| p f.external_encoding #=> #<Encoding:Windows-31J> p f.internal_encoding #=> #<Encoding:UTF-8> p f.gets().encoding #=> #<Encoding:UTF-8> end
UTF-8をShift JISに変換してファイルに出力。
open("test.txt", "w:windows-31j:utf-8") do |f| f.puts("ほげ") end
標準入力でShift JIS→UTF-8変換。
$stdin.set_encoding("Windows-31J", "UTF-8") gets()
標準出力でUTF-8→Shift JIS変換。
$stdout.set_encoding("Windows-31J", "UTF-8") puts("ほげ") #=> Shift JISで出力される
基本的にencodingが違う文字列を結合しようとするとエラー。
p "あ".encode("Shift_JIS") + "あ".encode("EUC-JP") # => character encodings differ (ArgumentError)
ただしASCIIのみからなる文字列はどんな文字列*2とも結合可能。
p ("あ" + "a".encode("EUC-JP")).encoding #=> #<Encoding:UTF-8>
ref. Ruby 1.9 の新機能を調べてみた