What is the purpose of "!" and "?" at the end of method names?
RubyMethodsSyntaxPredicateSyntactic SugarRuby Problem Overview
Sometimes I see methods in Ruby that have "?" and "!" at the end of them, e.g:
name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?
I was wondering what their purpose is? Are they just syntax sugarcoating?
Ruby Solutions
Solution 1 - Ruby
It's "just sugarcoating" for readability, but they do have common meanings:
- Methods ending in
!
perform some permanent or potentially dangerous change; for example:Enumerable#sort
returns a sorted version of the object whileEnumerable#sort!
sorts it in place.- In Rails,
ActiveRecord::Base#save
returns false if saving failed, whileActiveRecord::Base#save!
raises an exception. Kernel::exit
causes a script to exit, whileKernel::exit!
does so immediately, bypassing any exit handlers.
- Methods ending in
?
return a boolean, which makes the code flow even more intuitively like a sentence —if number.zero?
reads like "if the number is zero", butif number.zero
just looks weird.
In your example, name.reverse
evaluates to a reversed string, but only after the name.reverse!
line does the name
variable actually contain the reversed name. name.is_binary_data?
looks like "is name
binary data?".
Solution 2 - Ruby
Question mark indicates that the method returns boolean. Already answered here:
https://stackoverflow.com/questions/1345843/ruby-question-mark
The bang indicates that the method acts on the object itself. Already answered here:
https://stackoverflow.com/questions/612189/why-are-exclamation-marks-used-in-ruby-methods
Solution 3 - Ruby
In Ruby the ?
means that the method is going to return a boolean and the !
modifies the object it was called on. They are there to improve readability when looking at the code.
Solution 4 - Ruby
In contrast to the – I suppose – majority of programming languages ...
> Ruby, methods are allowed to end with question marks or exclamation marks. > > By convention, methods that answer questions (i.e. Array#empty? returns true if the receiver is empty) end in question marks. > > Potentially “dangerous” methods (ie methods that modify self or the arguments, exit! etc.) by convention end with exclamation marks.
From: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/, Section Funny method names
Solution 5 - Ruby
Beware, this isn't always the case. Take for example, Ruby Array#concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat.
Where you can get burnt badly is something like MyActiveRecordModel.column_names.concat([url])
. Later calls related to MyActiveRecordModel will try to look for a column of 'url' for MyActiveRecordModel and throw.
Instead you must clone it before doing the concat. Fortunately my test suite caught this one, but.. heads up!