CSV.generateメソッドでUTF-8の文字列をShift-JISに変換して書き込もうとしたら
U+2613 from UTF-8 to Windows-31J incompatible character encodings: UTF-8 and Windows-31J
というエラーが発生しました。
上記リファレンスに記載の通り、そのまま使うと文字コード変換で失敗する可能性があるので、適宜変換などして使う必要があります。
主に機種依存文字などが当てはまりますが、一つ一つ変換処理を定義するのもイタチごっこなので、潔く変換失敗文字列は全無視する方針にしました。
実装
def sjis_safe(str) str.encode(Encoding::SJIS, invalid: :replace, undef: :replace) end
pry(main)> '☓ほげほげ'.encode(Encoding::SJIS, invalid: :replace, undef: :replace).encode(Encoding::UTF_8) => "?ほげほげ"
使用例
CSV.generateでAppendしていく直前にsjis_safe
で変換するイメージです。
csv_string = CSV.generate(encoding: Encoding::SJIS, force_quotes: true) do |csv| csv << [ sjis_safe(name).encode(Encoding::UTF_8) ] end
Shift-JISを扱うときはこういう考慮が必然なので早く一掃されてほしいと願います。