There are multiple ways to check presence in Ruby. Let's see them with various examples.

· Ruby  · 6 min read

Check emptiness in Ruby, nil? vs blank? vs empty? vs presence?

There are multiple ways to check presence in Ruby. Let's see them with various examples.

“if” alone may not be enough

if false or if nil won’t execute the corresponding condition, because false and nil are considered as falsy values.

In other words, if you cast nil or false as a boolean, it will return false. Every other kind of value is considered truthy in Ruby. A quick hack (not only specific to Ruby, it also works with JavaScript) is to prepend a double exclamation mark before the variable.

!!nil        # nil => false
!!false      # boolean false => false
!!true       # boolean true => true
!!0          # number zero => true
!!42         # number other than zero => true
!!""         # empty string => true
!!" "        # spaces-only string => true
!!"sth"      # non-empty string => true
!![]         # empty array => true
!![nil]      # array with empty values => true
!!['a', 'z'] # non-empty array => true
!!{}         # empty hash => true
!!{a: nil}   # hash with empty values => true
!!{a: 42}    # non-empty hash => true
!!/regex/    # regex => true
!!Time.now   # any object => true

.nil? is from Ruby, check if object is actually nil

That’s the easy part. In Ruby, you can check if an object is nil, just by calling the nil? on the object… even if the object is nil. That’s quite logical if you think about it :)

Side note : in Ruby, by convention, every method that ends with a question mark is designed to return a boolean (true or false). In JavaScript, the convention is different : often, this kind of method starts with “is” (isEmpty, isNumeric, etc).

nil.nil?        # nil => true
false.nil?      # boolean false => false
true.nil?       # boolean true => false
0.nil?          # number zero => false
42.nil?         # number other than zero => false
"".nil?         # empty string => false
" ".nil?        # spaces-only string => false
"sth".nil?      # non-empty string => false
[].nil?         # empty array => false
[nil].nil?      # array with empty values => false
['a', 'z'].nil? # non-empty array => false
{}.nil?         # empty hash => false
{a: nil}.nil?   # hash with empty values => false
{a: 42}.nil?    # non-empty hash => false
/regex/.nil?    # regex => false
Time.now.nil?   # any object => false

.empty? is from Ruby, it checks if size is 0

.empty? is a Ruby method, which works only for Hash, Array, or String. But not for every Enumerable. It returns true if size is above zero. For others it returns a NoMethodError.

nil.empty?        # nil => NoMethodError
false.empty?      # boolean false => NoMethodError
true.empty?       # boolean true => NoMethodError
0.empty?          # number zero => NoMethodError
42.empty?         # number other than zero => NoMethodError
"".empty?         # empty string => true
" ".empty?        # spaces-only string => false
"sth".empty?      # non-empty string => false
[].empty?         # empty array => true
[nil].empty?      # array with empty values => false
['a', 'z'].empty? # non-empty array => false
{}.empty?         # empty hash => true
{a: nil}.empty?   # hash with empty values => false
{a: 42}.empty?    # non-empty hash => false
/regex/.empty?    # regex => NoMethodError
Time.now.empty?   # custom object => NoMethodError

.blank? is from ActiveSupport

.blank? Comes from wonderful ActiveSupport. ActiveSupport is a dependency of Rails, so if you are inside the Rails environment, you already have this method, for free.

The NoMethodError above could be annoying. So ActiveSupport adds a .blank? method that never fails.

Warning : what is considered as “blank” for Rails is opinionated. String with whitespace is considered “blank”, but not the number “0”. See the list here :

nil.blank?        # nil => true
false.blank?      # boolean false => true
true.blank?       # boolean true => false
0.blank?          # number zero => false
42.blank?         # number other than zero => false
"".blank?         # empty string => true
" ".blank?        # spaces-only string => true
"sth".blank?      # non-empty string => false
[].blank?         # empty array => true
[nil].blank?      # array with empty values => false
['a', 'z'].blank? # non-empty array => false
{}.blank?         # empty hash => true
{a: nil}.blank?   # hash with empty values => false
{a: 42}.blank?    # non-empty hash => false
/regex/.blank?    # regex => false
Time.now.blank?   # custom object => false

No more errors… but opinionated ways to define what is “blank” or not. So pay extra attention :

  • 0.blank? returns false. In my humble opinion, 0 should have been considered as a “blank” value. It would have been more consistent with other languages.
  • false.blank? returns true. Could be seen as weird or logical, depending on your habits.
  • [nil, ''].blank? returns false. An array of blank values is not considered as blank. This time, I find it logical because the method blank evaluates the array, not what’s inside the array.
  • Now the tricky part : [nil].any? returns false. But [''].any? returns true. It’s because the empty string is truthy. If you want to check that [nil, ''] doesn’t contain anything interesting, you can do it this way : [nil, ''].all?(&:blank?) returns true.

.present? is also from ActiveSupport

.present? is the negation of blank, so no surprise here :

nil.present?        # nil => false
false.present?      # boolean false => false
true.present?       # boolean true => true
0.present?          # number zero => true
42.present?         # number other than zero => true
"".present?         # empty string => false
" ".present?        # spaces-only string => false
"sth".present?      # non-empty string => false
[].present?         # empty array => false
[nil].present?      # array with empty values => true
['a', 'z'].present? # non-empty array => true
{}.present?         # empty hash => false
{a: nil}.present?   # hash with empty values => true
{a: 42}.present?    # non-empty hash => true
/regex/.present?    # regex => true
Time.now.present?   # custom object => true

Conclusion

As a memo, I put here this decision table, freely inspired by this Rails article.

Methodif ()nil?empty?any?blank?present?(!blank?)
Scoperubyrails only
ObjectallString, Array, HashEnumerableall
nilfalsetrueNoMethodErrorNoMethodErrortruefalse
falsefalsefalseNoMethodErrorNoMethodErrortruefalse
truetruefalseNoMethodErrorNoMethodErrorfalsetrue
0truefalseNoMethodErrorNoMethodErrorfalsetrue
42truefalseNoMethodErrorNoMethodErrorfalsetrue
""truefalsetrueNoMethodErrortruefalse
" "truefalsefalseNoMethodErrortruefalse
"sth"truefalsefalseNoMethodErrorfalsetrue
[]truefalsetruefalsetruefalse
[nil]truefalsefalsefalsefalsetrue
['a', 'z']truefalsefalsetruefalsetrue
{}truefalsetruefalsetruefalse
{ a: nil }truefalsefalsetruefalsetrue
{ a: 42 }truefalsefalsetruefalsetrue
/regex/truefalseNoMethodErrorNoMethodErrorfalsetrue
Time.nowtruefalseNoMethodErrorNoMethodErrorfalsetrue
Share:
Back to Blog

Related Posts

View All Posts »
Ruby constants

Ruby constants

Constant are not so often used in Ruby, however, it's always good to know how they work when the need arises. Constants are simply variables that are not meant to be changed.

How to create tons of Rails apps

How to create tons of Rails apps

Yes, I already now about the rails new command. But what if you want better defaults, like an existing controller, an existing view, or another way to to launch the Procfile?

Rails new options

Rails new options

Let's see the official way to create Rails application, as well as the minimalistic option.