How to understand nil vs. empty vs. blank in Ruby

Ruby on-RailsRuby

Ruby on-Rails Problem Overview


I find myself repeatedly looking for a clear definition of the differences of nil?, blank?, and empty? in Ruby on Rails. Here's the closest I've come:

  • blank? objects are false, empty, or a whitespace string. For example, "", " ", nil, [], and {} are blank.

  • nil? objects are instances of NilClass.

  • empty? objects are class-specific, and the definition varies from class to class. A string is empty if it has no characters, and an array is empty if it contains no items.

Is there anything missing, or a tighter comparison that can be made?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

.nil? can be used on any object and is true if the object is nil.

.empty? can be used on strings, arrays and hashes and returns true if:

  • String length == 0
  • Array length == 0
  • Hash length == 0

Running .empty? on something that is nil will throw a NoMethodError.

That is where .blank? comes in. It is implemented by Rails and will operate on any object as well as work like .empty? on strings, arrays and hashes.

nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
0.blank? == false

.blank? also evaluates true on strings which are non-empty but contain only whitespace:

"  ".blank? == true
"  ".empty? == false

Rails also provides .present?, which returns the negation of .blank?.

Array gotcha: blank? will return false even if all elements of an array are blank. To determine blankness in this case, use all? with blank?, for example:

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 

Solution 2 - Ruby on-Rails

I made this useful table with all the cases:

enter image description here

blank?, present? are provided by Rails.

Solution 3 - Ruby on-Rails

Just extend Julian's table:

enter image description here

Ref: empty?blank?nil?傻傻分不清楚

Solution 4 - Ruby on-Rails

Quick tip: !obj.blank? == obj.present?

Can be handy/easier on the eyes in some expressions

Solution 5 - Ruby on-Rails

enter image description here

  • Everything that is nil? is blank?
  • Everything that is empty? is blank?
  • Nothing that is empty? is nil?
  • Nothing that is nil? is empty?

tl;dr -- only use blank? & present? unless you want to distinguish between "" and " "

Solution 6 - Ruby on-Rails

One difference is that .nil? and .empty? are methods that are provided by the programming language Ruby, whereas .blank? is something added by the web development framework Rails.

Solution 7 - Ruby on-Rails

A special case is when trying to assess if a boolean value is nil:

false.present? == false
false.blank? == true
false.nil? == false

In this case the recommendation would be to use .nil?

Solution 8 - Ruby on-Rails

Just a little note about the any? recommendation: He's right that it's generally equivalent to !empty?. However, any? will return true to a string of just whitespace (ala " ").

And of course, see the 1.9 comment above, too.

Solution 9 - Ruby on-Rails

Don't forget any? which is generally !empty?. In Rails I typically check for the presence of something at the end of a statement with if something or unless something then use blank? where needed since it seems to work everywhere.

Solution 10 - Ruby on-Rails

nil? is a standard Ruby method that can be called on all objects and returns true if the object is nil:

b = nil
b.nil? # => true

empty? is a standard Ruby method that can be called on some objects such as Strings, Arrays and Hashes and returns true if these objects contain no element:

a = []
a.empty? # => true

b = ["2","4"]
b.empty? # => false

empty? cannot be called on nil objects.

blank? is a Rails method that can be called on nil objects as well as empty objects.

Solution 11 - Ruby on-Rails

Everybody else has explained well what is the difference.

I would like to add in Ruby On Rails, it is better to use obj.blank? or obj.present? instead of obj.nil? or obj.empty?.

obj.blank? handles all types nil, '', [], {}, and returns true if values are not available and returns false if values are available on any type of object.

Solution 12 - Ruby on-Rails

exists? method can be used to check whether the data exists in the database or not. It returns boolean values either true or false.

Solution 13 - Ruby on-Rails

Rails 4

an alternative to @corban-brook 's 'Array gotcha: blank?' for checking if an arrays only holds empty values and can be regarded as blank? true:

[ nil, '' ].all? &:blank? == true

one could also do:

[nil, '', "", " ",' '].reject(&:blank?).blank? == true

Solution 14 - Ruby on-Rails

Though there n-number of answers available to this question but I liked the way its being explained here so posted one more answer :-)

Look at the metric below - its self explanatory with the various data-types used across available methods for it.

The Metrics way of understanding functionality

Reference: https://blog.appsignal.com/2018/09/11/differences-between-nil-empty-blank-and-present.html

Solution 15 - Ruby on-Rails

nil? can be used on any object. It determines if the object has any value or not, including 'blank' values.

For example:

example = nil
example.nil?  # true

"".nil?  # false

Basically nil? will only ever return true if the object is in fact equal to 'nil'.

empty? is only called on objects that are considered a collection. This includes things like strings (a collection of characters), hashes (a collection of key/value pairs) and arrays (a collection of arbitrary objects). empty? returns true is there are no items in the collection.

For example:

"".empty? # true
"hi".empty?   # false
{}.empty?  # true
{"" => ""}.empty?   # false
[].empty?   # true
[nil].empty?  # false

nil.empty?  # NoMethodError: undefined method `empty?' for nil:NilClass

Notice that empty? can't be called on nil objects as nil objects are not a collection and it will raise an exception.

Also notice that even if the items in a collection are blank, it does not mean a collection is empty.

blank? is basically a combination of nil? and empty? It's useful for checking objects that you assume are collections, but could also be nil.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArrelView Question on Stackoverflow
Solution 1 - Ruby on-RailsCorban BrookView Answer on Stackoverflow
Solution 2 - Ruby on-RailsJulian PopovView Answer on Stackoverflow
Solution 3 - Ruby on-RailsSibevin WangView Answer on Stackoverflow
Solution 4 - Ruby on-RailsAlexander MalfaitView Answer on Stackoverflow
Solution 5 - Ruby on-RailssteveView Answer on Stackoverflow
Solution 6 - Ruby on-RailsAndrew GrimmView Answer on Stackoverflow
Solution 7 - Ruby on-RailsAlan HView Answer on Stackoverflow
Solution 8 - Ruby on-RailsdavemyronView Answer on Stackoverflow
Solution 9 - Ruby on-RailsAndyView Answer on Stackoverflow
Solution 10 - Ruby on-RailsnehaView Answer on Stackoverflow
Solution 11 - Ruby on-RailsManish ShrivastavaView Answer on Stackoverflow
Solution 12 - Ruby on-RailskelvinView Answer on Stackoverflow
Solution 13 - Ruby on-RailsmahatmanichView Answer on Stackoverflow
Solution 14 - Ruby on-RailsshahjapanView Answer on Stackoverflow
Solution 15 - Ruby on-RailsChitraView Answer on Stackoverflow