Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do some Ruby methods need a bang and others don't to be a destructive method?

Tags:

methods

ruby

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?

like image 474
Aaron Avatar asked Aug 13 '14 18:08

Aaron


3 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, poping 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
like image 172
Patrick Oscity Avatar answered Oct 09 '22 22:10

Patrick Oscity


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.

like image 40
Jörg W Mittag Avatar answered Oct 09 '22 22:10

Jörg W Mittag


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.

like image 1
Nick McCurdy Avatar answered Oct 09 '22 22:10

Nick McCurdy