Ruby 1.9.3 以降では String#encode
の fallback
オプションに Proc が指定できるようになっている。
未定義文字がある場合、これを引数として、fallback に指定した Proc が呼び出され、返り値の文字列に置き換えられる。
下記では Windows-31J に無い文字を HTML の数値文字参照に置き換える例を示す。
replace_with_charref = -> char {
char.codepoints.map{|cp| "##{cp};"}.join
}
"\u{00ae} is registered sign.".encode("windows-31j", fallback: replace_with_charref)
# => "#174; is registered sign."
1.9.2 では Hash しか指定できず、下記のようにしてみてもうまくいかなかった (同じコードは 1.9.3, 2.0.0 では期待通り動作する)。
# キーがない場合、キーに対応する数値文字参照を返す Hash
replace_with_charref = Hash.new {|hash, char|
char.codepoints.map{|cp| "##{cp};"}.join
}
"\u{00ae} is registered sign.".encode("windows-31j", fallback: replace_with_charref)
# => Encoding::UndefinedConversionError: U+00AE from UTF-8 to Windows-31J
1.9.2 で同等のことを実現するためには Encoding::Converter#primitive_convert
を用いる必要がある。