Read this post especially the comments.
Actually it's not that much of a gotcha. Ruby's convention with methods that end with a '!' is that the method would do something surprising. In this case, upcase! changes String instances in place. So you shouldn't depend on the return value nor use it in an assignment.
The convention is:
some_string.upcase!
So upcase!
is not supposed to be used in an assignment as it changes the string in place. Rather the use is to check for truth like if str.upcase!
. A more intuitive example is gsub!
, it returns nil if no substitution was done:
"abc".gsub!('d','') #=> nil