This feature of ruby keeps catching me out as the behaviour is quite unexpected (by me).

I can use a ‘!’ modifying function like so:

html_string.gsub!("<pre>","<pre class=\"prettyprint\">")

Which works great apart from when the match string “<pre>” in this case is not found then it returns nil. Surely I would want the string unaltered instead, why would I want nil. So I generally have to replace it with the following:

html_string = html_string.gsub("<pre>","<pre class=\"prettyprint\">")

[Update 27/04/2010]

Turns out it should not modify the the string but the function returns nil. This was the last line in a function call and so was an implicit return. The following would probably have been better:

html_string.gsub!("<pre>","<pre class=\"prettyprint\">")
return html_string

The returned nil could then be used as an if statment to take a different execution path if not modified:

if /<pre>/ === html_string
   html_string = html_string.gsub("<pre>","<pre class=\"prettyprint\">")
else
   puts "Does not contain <pre>"
end

Could just become:

if not html_string.gsub!("<pre>","<pre class=\"prettyprint\">")
   puts "Does not contain <pre>"
end