Ruby's syntax allows you to postfix a single ?
or !
to your method names (both or more than one of each is invalid).
This is to support a couple of deeply ingrained conventions:
method?
:
A method that returns a boolean and doesn't modify its receiver's state should use a ?
. For example, if you want to "ask" whether a container is sorted, you might use my_obj.sorted?
. If you want to "ask" whether a container is empty, you might use my_obj.empty?
. Neither of these methods would modify their receiving object's state. See String
for many examples of ?
methods being used to interrogate an object without modifying it, such as start_with?
and end_with?
.
method!
:
A method that has a !
at the end destructively modifies its objects state. By extension, when a method might destructively transform an object's state, there are often two versions of the method provided, with and without a !
. In the case of an array, you might have a pair of methods called sort
and sort!
. sort
will return a copy of the array, in sorted order, without modifying the original copy. After calling sort
, you will have two copies, including an unmodified version of the original. sort!
however, will sort the array in-place, overwriting the original array.
Again, referring to String
, we have methods such as capitalize
which returns a capitalized copy of a string, and capitalize!
which capitalizes the string in-place:
x = "what"
y = x.capitalize
puts x # "what"; x is unchanged
puts y # "What"
x = "what"
y = x.capitalize!
puts x # "What"; x is changed in-place
puts y # "What"
It's worth noting that Rails has its own conventions for the semantics of !
. In Rails, a method that can fail (such as a database write) will typically return true
or false
. Rails uses a !
to indicate that the method should fail with an exception, instead of a false
return value. For example, my_record.save
will return false
on failure; my_record.save!
will raise an exception.