Ruby 1.9.0 の ERB ではテンプレートの encoding が欠落する
やっぱりさっきの予想は的中。以下のソースで確認した。
require 'erb' data = "データ" rhtml = "テンプレート + <%= data %>" erb = ERB.new(rhtml) puts "data: #{data.encoding}" puts "rhtml: #{rhtml.encoding}" puts "erb.src: #{erb.src.encoding}" puts erb.result(binding)
このプログラムを --encoding=ETC-JP オプションをつけて実行する。
$ ~/local/bin/ruby --encoding=EUC-JP test.rb data: EUC-JP rhtml: EUC-JP erb.src: ASCII-8BIT (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:14:in `<main>'
ERB.new の引数で渡したときは EUC-JP なのに、内部でコンパイルすると ASCII-8BIT になっている。 それで、 ASCII-8BIT のソースを eval で実行するときに、 EUC-JP な data を埋め込もうとしてエラーになると。
ERB の仕組みが分かっていないけど、とりあえず以下のパッチで対処した。
$ diff -u erb.rb.org erb.rb --- erb.rb.org Fri Dec 28 23:05:02 2007 +++ erb.rb Fri Dec 28 23:05:18 2007 @@ -689,6 +689,7 @@ compiler = ERB::Compiler.new(trim_mode) set_eoutvar(compiler, eoutvar) @src = compiler.compile(str) + @src.force_encoding(str.encoding) @filename = nil end
今度は期待した動作になったよ。これで先に進めるかな。
$ ~/local/bin/ruby --encoding=EUC-JP test.rb data: EUC-JP rhtml: EUC-JP erb.src: EUC-JP テンプレート + データ