添字に正規表現を使って置換
RubyではString#[]=で正規表現を指定すると破壊的な置換ができます。
以下の例では、strが保持しているStringオブジェクトを書き換えてcolorをflowerにしています。
str = 'Do you like this color?' str[/color/] = 'flower' p str #=> "Do you like this flower?"
以下の例のようにString#subを使っても類似のことができます。この場合はsubメソッドの戻り値が置換後の新しい文字列になり、レシーバ自体は変わりません。
str = 'Do you like this color?' p str.sub(/color/, 'flower') #=> "Do you like this flower?" p str #=> "Do you like this color?"
追記:
なお、はじめの例で、確かにオブジェクトの中身が書き換わっていることを確認してみます。以下のプログラムでは、置換を行う前に変数otherも同じオブジェクトを保持するようにしています。置換後、str, otherが同じように変わっているのでstrに別のオブジェクトが代入されたわけではないことがわかります。また、object_idも置換前後で変わっていないので、まさにそのオブジェクトの内部状態が変化しているのだということがわかります。
str = 'Do you like this color?' other = str; p str.object_id #=> 23059010 p other.object_id #=> 23059010 str[/color/] = 'flower' p str #=> "Do you like this flower?" p str.object_id #=> 23059010 p other #=> "Do you like this flower?" p other.object_id #=> 23059010
String#subではなくString#sub!を使えばString#[]=と同じことが実現できます。名前に!がついているメソッドは取り扱いに注意が必要なもので、ここではレシーバを書き換えていることを表現しています。
str = 'Do you like this color?' other = str; p str.object_id #=> 23059010 p other.object_id #=> 23059010 str.sub!(/color/, 'flower') p str #=> "Do you like this flower?" p str.object_id #=> 23059010 p other #=> "Do you like this flower?" p other.object_id #=> 23059010