# Bang Methods In Ruby

> Why the '!' in Ruby is so important to conquer and real-world implications.

- Canonical: https://dennisokeeffe.com/blog/2022-02-16-bang-methods-in-ruby
- Published: 2022-02-16
- Updated: 2022-02-16
- Tags: ruby

After working with so many other languages, one of the unusual things that stood out with the Ruby language was the way that the '!' symbol was used with methods.

Why were there methods like `reverse` _and_ `reverse!`? How does this impact the code? This short post looks to address just that.

## Hello, bang!

When we are talking about collections, something that you may find unintuitive is that certain methods such as `reverse` **do not actually modify the collection**.

What do I mean? Well open up a REPL such as `irb` and you can see what I am talking about in action:

```rb
irb(main):001:0> a = [1,2,3]
=> [1, 2, 3]
irb(main):002:0> a.reverse
=> [3, 2, 1]
irb(main):003:0> a
=> [1, 2, 3]
```

Notice that although `a.reverse` returns a new collection, `a` is not modified. We can further demonstrate this by assigning the value of `a.reverse` to another variable.

```rb
irb(main):004:0> b = a.reverse
=> [3, 2, 1]
irb(main):005:0> b
=> [3, 2, 1]
irb(main):006:0> a
=> [1, 2, 3]
```

Above, you can see that `b` is in fact the reverse of `a`, but `a` itself was not modified.

What happens if we want to modify the collection in place? Well, we could reassign `a` with `a = a.reverse`, but even better is to use the bang method `reverse!` to accomplish this.

```rb
irb(main):011:0> a
=> [1, 2, 3]
irb(main):012:0> a.reverse!
=> [3, 2, 1]
```

So does this mean that the bang `!` symbol on methods will only be used for altering collections? Not quite.

In Ruby, the convention is that the bang `!` symbol is used for to indicate that the method is the "dangerous" or surprising version of a pair of methods. That means that there are methods without the `!` that will still modify the data. Some more obvious examples of this (when talking about collections) are `push` and `pop`.

## Bang in the wild

Another common example where the `!` alternative method shows up is when dealing with Ruby on Rails.

Both the `destroy` and `save` methods come with the alternate pair `destroy!` and `save!`.

So what's the difference?

The documentation has more, but the most prominent different is that the `!` method will raise an exception if the method fails (`ActiveRecord::RecordNotDestroyed` and `ActiveRecord::RecordNotSaved` for `destroy!` and `save!` respectively), while the bang-less alternative will return `false` if the method fails.

Whenever you see the `!` in the name of a method, the best thing you can do is refer to the relevant documentation to define what the difference between both implementations of the methods are.

## Summary

Today's post is a short overview on pattern matching, how it differs from case statements and how it can be used to solve a variety of matching problems.

## Resources and further reading

- [Ruby Docs: Array#reverse](https://ruby-doc.org/core-3.1.0/Array.html#reverse-method)
- [ActiveRecord::Persistence#destroy](http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-destroy)
- [ActiveRecord::Persistence#save](http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-save)
