Ruby Advent Calendar 2013 7日目担当 @sonots です。
昨日は yujinakayama さんの RSpecの最新の動向・RSpec 3へのアップグレードガイド の記事でした。
今日は ruby 2.1.0 に新しく追加される String#scrub を取り上げたいと思います。
背景
以前、私はRuby の invalid byte sequence in UTF-8 例外を encode("UTF-8", "UTF-8") で回避するのはおかしいよ、という話を書きました。簡単に要約すると、
1.Ruby 1.9 で UTF-8 文字列に対して正しくないバイト列があると、正規表現マッチや gsub といったメソッドを使っているところで ArgumentError: invalid byte sequence in UTF-8
例外が発生する
2.ぐぐると
のようなコードで回避できる、という記述が見つかる
3.しかし本来String#encode
は src_encoding と dst_encoding に同じエンコードを指定すると変換処理をしない仕様。つまり、例外が起きなくなるのはバグなのでこのコードを使っているとまずい (2.0.0 で例外が起きるように修正された)
4.よって、正しくは
のようにするのだが、
5.そもそも不正バイトを除去する専用のメソッドが欲しい
という話でした。これに対して、ruby 2.1.0 には不正なバイト列を代替文字に置き換える String#scrub メソッドが追加されました。o(・∇・o)(o・∇・)o ヤッタ!
String#scrub の使い方
サンプルコードは以下のようになります。不正なバイト列を ? に置き換えています。
他にも str.scrub!('?')
といった破壊的メソッドも用意してありました。以下、API 仕様です。
- str.scrub
- Unicode 系ならば U+FFFD (Replacement Character) を置換文字とし、それ以外の場合は ? を置換文字とする。
- str.scrub('**')
- 指定した文字列を置換文字とする。
- str.scrub{|x| '' }
- ブロック引数として不正なバイト列を与え、引数を置換文字とする。
String#scrub を 2.0 で使う
@hsbt 氏が string-scrub という gem を用意してくださっているので、ruby 2.0 でもこの gem をインストールすれば利用できます。
gem install string-scrub
のようにインストールし
のように require すればOKです。
追記: 2014/02/26: string-scrub gem が 1.9 でも動くようになりました!
まとめ
ruby 2.1.0 に追加される不正なバイト列を代替文字に置き換える String#scrub メソッドの紹介をしました。ますます便利になりますね!@nalsh さんありがとうございます!
明日は aoitaku さんです。