Ruby 1.9.0 の ERB ではテンプレートの encoding が欠落する
2007-12-28
やっぱりさっきの予想は的中。以下のソースで確認した。
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
テンプレート + データ