Ruby1.9 で --encoding オプションはつけないほうが幸せ?
tDiary2.2 + Ruby1.9.0 でマルチバイト文字を含む日記を入力すると "character encodings differ" が発生する問題。 いろいろ試してみたけど、どうも ERB がテンプレートを解釈しようとしたときに起きているみたい。
以下のサンプルで再現してみた。ソースコードは EUC-JP で書いている。
require 'erb' data = "データ" rhtml = "テンプレート + <%= data %>" puts "data: #{data.encoding}" puts "rhtml: #{rhtml.encoding}" puts ERB::new(rhtml).result(binding)
起動時の引数で文字コードを指定しなければ、特に問題なく動作する。 このときのエンコーディングは ASCII-8BIT として扱われている。
$ ~/local/bin/ruby test.rb data: ASCII-8BIT rhtml: ASCII-8BIT テンプレート + データ
デフォルトエンコーディングを EUC-JP にすると、 "character encodings differ" が発生する。
$ ~/local/bin/ruby --encoding=EUC-JP test.rb data: EUC-JP rhtml: EUC-JP (erb):1:in `concat': character encodings differ (ArgumentError) from (erb):1:in `<main>' from /home/machu/local/lib/ruby/1.9.0/erb.rb:743:in `eval' from /home/machu/local/lib/ruby/1.9.0/erb.rb:743:in `result' from test.rb:12:in `<main>'
data と rhtml の encoding 指定を変えた結果は以下の通り。
data (ASCII-8BIT) | data (EUC-JP) | |
rhtml (ASCII-8BIT) | ○ | × |
rhtml (EUC-JP) | ○ | × |
ここから推測するに、 ERB に渡したテンプレート (rhtml) は、 encoding 情報が欠落して内部では ASCII-8BIT として扱われているんじゃないかな。 これって正しい挙動?それともバグ? さて、どうしたものか。 --encoding=EUC-JP を指定して、 ERB に渡すときだけ ASCII-8BIT として扱う? でもそれだと、マルチバイトを含む正規表現を使っていた場合にうまく動かなくなりそう。