3

Can someone explain what the difference is between the two pieces of code below? Both feature an ! at the end. Is the first version just the shorthand?

print "Who are you?" 
user_input = gets.chomp.downcase!

print "Who are you?"
user_input = gets.chomp
user_input.downcase!
sawa
  • 165,429
  • 45
  • 277
  • 381
zbiber
  • 143
  • 2
  • 11
  • 3
    You don't need bang in the first case, you do need it in the second. – BroiSatse Apr 04 '14 at 15:42
  • possible duplicate of [Why are exclamation marks used in Ruby methods?](http://stackoverflow.com/questions/612189/why-are-exclamation-marks-used-in-ruby-methods) – Wooble Apr 04 '14 at 15:44
  • @Wooble I don't think it is a dup post. This post has different intention.. – Arup Rakshit Apr 04 '14 at 15:45
  • 1
    It's important to understand what `downcase` and `downcase!` return when each letter in the string is already lower case: `"Abc".downcase! => "abc"`, `"abc".downcase => "abc"`, `"abc".downcase! => nil`. Many Ruby methods ending `!` have similar behavior: they return `nil` if no change is made. – Cary Swoveland Apr 04 '14 at 16:18

1 Answers1

5

Edit: Having an exclamation point (aka "bang") at the end of a method name in ruby means "handle with care". From Matz himself:

The bang (!) does not mean "destructive" nor lack of it mean non destructive either. The bang sign means "the bang version is more dangerous than its non bang counterpart; handle with care". Since Ruby has a lot of "destructive" methods, if bang signs follow your opinion, every Ruby program would be full of bangs, thus ugly.

(For the full thread, see @sawa's link in the comments.)

For the method in question, downcase is making a copy of the given string, modifying that, and returning that copy as a result. Whereas downcase! modifies the string itself.

In the first case, you're modifying the variable stored in gets.chomp, in the second you're modifying user_input.

Note that if you call user_input.downcase on the last line (instead of user_input.downcase!) it won't actually change user_input, it just returns a copy of the string and makes the copy lowercase.

mralexlau
  • 1,823
  • 1
  • 16
  • 23
  • 1
    I was going to ask about BroiSatse's comment that "_You don't need bang in the first case, you do need it in the second_" (why is that the case?) but you answered it. – damianesteban Apr 04 '14 at 16:20
  • 2
    This answer is wrong, as well as the accepted answer to the question you linked. The correct answer is: https://www.ruby-forum.com/topic/176830#773946. – sawa Apr 04 '14 at 16:30
  • 1
    Wow, thanks @sawa. I didn't know that was its official definition (which also explains why `Array.push` and `Array.pop` don't have exclamation points at the end). I've updated my answer and referenced your comment in it. – mralexlau Apr 04 '14 at 17:29