すがブロ

sugamasaoのhatenablogだよ

+暗が gsub できない

これは Ruby の不具合?

JISコードの +暗 という文字を gsub*1の第二引数として渡すと文字化けする。
以下のようなスクリプトで検証してみる。

検証環境

ちなみに、Linux 版の ruby 1.8.6 でも同じ現象を確認している

入力ファイル

test.txt という名前にして、文字コードをJIS(ISO-2022-JP)で作成

+暗

検証スクリプト

ruby -e "str='test'; file = File.read('test.txt').chomp; puts str.gsub('test', file)" > res.txt

str に代入している test という文字列を、 gsub メソッドを使ってファイルから読み出した +暗 に置換する処理を実行している。
しかし、そのまま標準出力にだすと JIS をうまく解釈してくれないので一旦別ファイルへリダイレクトして検証してみる。

結果


これは Mac の CotEditor で表示しているのだけど、そもそも JIS コードとして認識できず*2、 UTF8 で表示されてしまっている。
念のため書いておくと、他の文字はほとんど問題なく置換できている。しかし、たまたま上記の文字の組み合わせがあったときにおかしくなっているのを発見できただけで、他の文字の組み合わせでどうなのかはよくわからない。他にもNGな組み合わせがあるかもしれない。
また、結果を見た感じだと、JISコードで使用される制御コードはあるのに、肝心の文字列を現すバイト列だけが置換されていないように見える。

回避策

以下のように、 gsub をブロック構文にして実施すると正しく置換される。

ruby -e "str='test'; file = File.read('test.txt').chomp; puts str.gsub('test') { file }" > res.txt

結果


ちゃんと JIS コードで表示できている

まとめ

なぜか、 gsub の第二引数を使用する方法だと特定の組み合わせでダメになる(バイトの並びに問題が?)。ただし、ブロック構文を用いて使用すると問題なく処理ができる。
・・・これって不具合でしょうか><

*1:または sub

*2:エンコーディングを JIS にすると警告が出て閲覧できない