A concise explanation of nil v. empty v. blank in Ruby on Rails

Arrel Source

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?



answered 9 years ago Andrew Grimm #1

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.

answered 9 years ago Andy #2

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.

answered 9 years ago Corban Brook #3

.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 

answered 9 years ago davemyron #4

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.

answered 8 years ago Alexander Malfait #5

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

Can be handy/easier on the eyes in some expressions

answered 6 years ago Alan H #6

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?

answered 4 years ago Julian Popov #7

I made this useful table with all the cases:

enter image description here

answered 4 years ago Sibevin Wang #8

Just extend Julian's table:

enter image description here

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

answered 3 years ago neha #9

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.

answered 3 years ago Manish Shrivastava #10

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.

answered 3 years ago mahatmanich #11

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

answered 3 years ago Chitra #12

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.

answered 2 years ago kelvin #13

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

answered 4 months ago steve #14

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 " "

comments powered by Disqus