Chances are during your course of learning ruby, you will come across some exclamation marks in your ruby code. Most people know this as a plain ol' "exclamation mark" (!). And they are happy with that. But not us Rubyists! we call these little guys bangs. If you are like me when you first saw this operator, you may have been a little intimidated by its implications and implementations. However, studying the documentation and practicing the functionality can help us understand the use of bangs. In this post I will discuss pairing bang methods with other built-in ruby methods and what that means for your code.
What is a bang?
When paired with other built-in ruby methods, the bang operator will change the original object the method is called on in place of creating a new object.
For example let's say we have an array of numbers and we only wanted to see the the unique numbers in that array. Luckily for us, ruby has a built in method called .uniq.
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 9, 9, 9, 9]
array.uniq
This would output
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
When we then call the original array object, ruby will output just that. The original unaltered array.
array
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 9, 9, 9, 9]
When we pair the .uniq method with the bang operator, we seemingly accomplish the same thing.
array.uniq!
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
However, when we call on the original array object, something different happens. We no longer have access to all of the original elements particularly those we excluded with the .uniq method. This is due to the functionality of the bang operator. Remember, the bang operator works with ruby's methods to alter the existing object- not create a new object.
array
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
At first glance, this seems, great! We can clean up our code and cut out many lines of code without having to assign new variables to new objects created by our built in methods. If only that were the case. The bang operator has another functionality. When called, it coerces our data into boolean expressions and inverts the truth value of that data.
For example...
!true
=> false
!false
=> true
Let's take another look at our array. It's not unlikely that at a later point we would want to call on our array object. However, if we were to forget that we had previously called the .uniq! method, and we used that method again...
array.uniq!
=> nil
we would no longer get our array of unique elements. Instead we would receive a nil value. This is due to the bang operators boolean inversion functionality.
Conclusion
The bang operator has its use in ruby and in a later article I will discuss more practical applications of the bang operator. like != or not equals to and the double bang (!!) operator. However, it is important to understand what a bang does and how it modifies methods first. Because the bang operator is destructive by nature, use caution when pairing it with other methods
Top comments (2)
Good article.
Keep in mind that both
method!
andmethod?
in ruby methods are a convention and not a ruby functionality per se, and it's different of the!method
and!!method
in the context of a boolean return. Something curious though:!true === true.!
.Talking about the convention, when I define methods I usually define them with
!
if the action is going to modify the object it's called on, or if it's going to raise an exception if something goes wrong. For the?
, the convention is that it will return aboolean
.PS: I love Ruby.
Excellent article! I learned a lot!