The Differences Between #nil?, #empty?, #blank?, and #present?
Ruby on Rails has a number of helpful methods that help you determine if certain objects meet certain conditions.
But where it gets tricky is understanding the subtle differences between a few of these similar methods.
Something can be empty but not nil... or even blank but not empty. That's definitely confusing.
Skipping ahead:
How the #nil? Method Works
In Ruby, everything is an object and all classes of objects inherit the nil?
method.
This means can call .nil?
on literally anything!
All it does is check to see if this object is an instance of NilClass, in which it returns true
.
If this object is any other class it returns false. Zero, empty lists, hashes, or any falsey value (besides nil) returns false when nil?
is called on it.
nil.nil? # => true
"".nil? # => false
false.nil? # => false
[].nil? # => false
{}.nil? # => false
0.nil? # => false
How the #empty? Method Works
The empty?
method checks the length of an object to determine if there is anything in it or not.
So we can only call the empty?
method on a string, hash, array, or even set.
The length of the object must be zero to return true.
This means even a string with whitespace will have a length greater than 0 and will not be considered empty when empty?
is called on it.
Here's an example of how various objects respond to the empty?
method:
[].empty? # => true
{}.empty? # => true
"".empty? # => true
" ".empty? # => false
nil.empty? # => NoMethodError
false.empty? # => NoMethodError
0.empty? # => NoMethodError
Again, we can only call empty?
on certain objects that have an implied length so booleans, numbers, and nil
values will raise exceptions if you try to call this method on them.
How the #blank? Method Works
The blank?
method isn't a standard Ruby method and requires the ActiveSupport module from Rails.
It's very similar to the empty?
method with one exception.
Whitespace allows a string to be considered blank?
but not empty?
.
[].blank? # => true
{}.blank? # => true
"".blank? # => true
" ".blank? # => true
nil.blank? # => true
false.blank? # => true
true.blank? # => false
0.blank? # => false
Another way to demonstrate this is with the all?
method which we'll cover in the future.
[ "", " ", [], {}, false, nil ].all?(&:blank?) # => true
How the #present? Method Works
The present?
method is the opposite of the blank?
method. It checks to see if there are any values in the given object.
Whitespace is considered the same as an empty just like the blank?
method too.
Also, any number is considered present and booleans are present if they evaluate to true
.
[].present? # => false
{}.present? # => false
"".present? # => false
" ".present? # => false
nil.present? # => false
false.present? # => false
true.present? # => true
0.present? # => true
"hello".present? # => true
Another way to demonstrate this is with the any? method.
We can call our .present?
method on an entire list and see if any element meets our condition.
[ "", " ", [], {}, false, nil ].any?(&:present?) # => false