新井です。
つい最近、ハマッたのですが"!"が付かないStringのメ
ソッドは、*変更がなされない場合に*レシーバそのもの
を返すんですね。
["foo", "BAR"].each {|src|
dest = src.upcase
printf "%x -> %x\n", src.id, dest.id
}
=>
2007de30 -> 2007de08 # 新しいオブジェクトを生成
2007de26 -> 2007de26 # 同じオブジェクト
! が付かないStringのメソッドの戻りは常にコピーだと
信じてたため、不用意に上記で言うところの dest に対
して、gsub! したときにsrc が変わってしまいました。
マニュアル:
| `!'のついていない同じ名
| 前のメソッドは文字列のコピーを作ってそちらを更新しますのでやや遅いです
| が,より安全です.例えば:
FAQ:
| 7.19 subとsub!はどう違うのですか
|
| subの場合はレシーバの状態は変化せず,コピーにsubが施されます.
ドキュメント上は、str.dup.sub!() なイメージで書か
れてる(と私は受け取った)ので、結構現在の仕様に気が
付いてない人は多いのでは?と思いました。
で、仕様変更(常に新しいオブジェクトを生成)または
現仕様のドキュメントへの明記をお願いしたいのですが、
いかがでしょう?