公式ドキュメントによると、「sub! は通常 self を変更して返しますが、 置換が起こらなかった場合は nil を返します。」とある。
が、それだと説明できない挙動がある。
a='abd';a.sub!('abd','abc') # => 'abc'
a='abc';a.sub!('abc','abc') # => 'abc'
a='abc';a.sub!('foo','abc') # => nil
この例1-2で、置換が発生していないにもかかわらずselfが返ってきている。
これは「パターンマッチが発生しなかった場合はnilを返す」と解釈すると説明がつく。
特に正規表現を使う場合、この誤解は致命傷だと思う。
a='abd';a.sub!(/a\w+/,'abc') # => 'abc'
a='abc';a.sub!(/a\w+/,'abc') # => 'abc'
この例2-2が「pattern /a\w+/がマッチした結果が replace と一致するため」nilを返すという誤解を、私は10年以上持ち続けていた。