Search code examples
rubystringsyntaxupcase

Ruby string upcase! method - uppercasechar.upcase! returns nil - bug or feature?


puts 'A'.upcase! returns nil. This is kind of confusing, especially since 'Ab' returns 'AB', not 'B'. Is this a bug or a language quirk?

edit so I see the docs, but it still seems counterintuitive. When would this make sense in a real usage scenario? I could see it causing more problems than helping

edit Tihom's answer seems like the best one; the post and comments he refers to brought me to understand that Matz and the Ruby dev team were most likely motivated by consistency in the integrity of the data types (that a string should be immutable) rather than the sensibility of the chained method in spoken English.

It seems that the upcase! for single characters is a bit of an odd duck for which there's no practical use and is a bit of a pathological case that really is counterintuitive for english speakers. Tihom notes that other instances of Ruby's prioritization of string immutability are more reasonable:

A more intuitive example is gsub!, it returns nil if no substitution was done:

"abc".gsub!('d','') #=> nil


Solution

  • 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