For example, array.pop
doesn't need a bang to permanently alter the array. Why is this so and what was the reasoning behind developing these certain Ruby methods without this conformity?

- 17,658
- 5
- 50
- 82

- 6,466
- 7
- 37
- 75
-
Is this case with ruby in general, or with Rails, or with some subset of Rails, like ActiveRecord? – xyz Aug 13 '14 at 18:19
-
This convention is used within the Ruby community in general. – Nick McCurdy Aug 13 '14 at 18:20
4 Answers
Bang methods are most commonly used to distinguish between a dangerous and a safe version of the same method. Here are some example cases that one might want to distinguish with a bang/no-bang combination:
- mutator methods - one version changes the object, the other one returns a copy and leaves the original object unchanged
- when encountering an error, one version throws an exception while the other one only writes an error message to the log or does nothing
However, the convention is to leave the bang off if there is only one version that makes sense. For example, pop
ing an array without actually changing it makes no sense. In this case, it would end up being a different operation: Array#last
. A lot of methods change the object they are called on, for example setters. We don't need to write these with a bang either, because it's clear that they change the object.
Lastly, there are a few exceptions to this, where some developers might use a bang method without implementing a bang-less counterpart. In these cases, the bang is simply used as a way to making the method calls stand out visually. For example:
- the method does something dangerous or destructive
- the method does something unexpected
- the method has a significant performance impact

- 53,604
- 17
- 144
- 168
-
2In addition some frameworks extend conventions of using `!` to mean "does something you might not expect" - so methods that are designed to control flow by conditionally raising exceptions, or no-parameter persistent mutators (e.g. `model_object.activate!`). However, these are sometimes a single development team's idea for the convention, and not Ruby-wide. – Neil Slater Aug 13 '14 at 18:25
-
This is partially incorrect. While what you're saying about `pop` is accurate, the `!` suffix does not mean that something is a mutator, it means that it is dangerous. Refer to my answer and my example of `ActiveRecord::Base#save!`. – Nick McCurdy Aug 13 '14 at 18:26
-
@NeilSlater very useful remarks. Additionally, I have seen bang methods being used to denote that the method might have a significant performance impact. – Patrick Oscity Aug 13 '14 at 18:27
-
The bang is used to distinguish between a dangerous and less dangerous version of the same method. There is only one pop
method, so there is nothing to distinguish.
Note: the name of the method has absolutely nothing whatsoever to do with what it does. Whether a method is destructive or not depends on what code it executes, not what name it has.

- 363,080
- 75
- 446
- 653
A suffix of !
means that a method is a dangerous version of another method. For example, save!
is the dangerous version of save
. Dangerous could mean editing in place, doing something with more strict errors, etc. It is not required to use the !
suffix on a method that is dangerous, but doesn't need a safer counterpart. Additionally, this is just a naming convention, so Ruby does not restrict what you can and can't do if a method does or doesn't end with !
.
There is a common misconception that every method that edits something in place should end with !
. This is not true, !
is only needed when there is a more dangerous version of a method that already exists, and this does not necessarily mean that the dangerous method edits in place. For example, in Rails, ActiveRecord::Base#save!
is a version of ActiveRecord::Base#save
that performs validations.

- 17,658
- 5
- 50
- 82
-
2
-
1That is the point. No, Ruby does not have an `Array#pop!` method. – Patrick Oscity Aug 13 '14 at 18:22
-
No, because `Array#pop` is already dangerous because it edits in place, and doesn't need a dangerous version. – Nick McCurdy Aug 13 '14 at 18:28
-
2@NicolasMcCurdy Your second sentence kind of implies that a `pop!` method actually does exist... I'd use an example other than pop right there – JKillian Aug 13 '14 at 18:39
-
Oops, I didn't catch that. I have now updated my answer. Thank you. – Nick McCurdy Aug 13 '14 at 18:40
The meaning of bang in Ruby is "caution". It means you should use the method with caution, nothing more. I cannot find the reference anymore, but people of authority said explicitly that bang ≠ destructive method. Bang is just a semantic element associated with caution. It is up to the programmer to weigh in everything and decide when to use bang.
For example, in my simulation gem, I use #step
method to obtain the step size.
simulation.step #=> 0.42
and step!
method to actually perform the simulation step.
simulation.step! #=> takes the simulation to the next time step
But as for #reset
method, I decided that the word "reset" it's verbose enough and it is not necessary to use bang to warn the user that the simulation state will be destroyed:
simulation.reset #=> resets the simulation back to the initial state
P.S.: Now I remember, once upon a time, Matz said half jokingly that he regrets introducing methods with bang into Ruby at all, because bang is semantically so ambiguous.

- 12,444
- 5
- 57
- 74