The Ultimate Guide to nil?, empty?, and blank?

Haji Furukawa
Bottega8 Posts
Published in
6 min readSep 23, 2015

So you might be doing some ruby on rails coding and you see stuff like .nil?, and .empty? and .blank? and wonder what the heck is the difference between them all? I thought the same thing and here’s what the Google gods have told me:

.nil?

  1. .nil is available on every class
  2. It’s defined in the ‘Object’ class and overridden in the ‘NilClass’ class
  3. .nil? returns true if the object is nil, and is available on all objects.
  4. e.g.
a. nil.nil? => true b. “helloworld”.nil? => false

.empty?

  1. .empty? is only available on strings, arrays, and Hashes. If you try to call it on other objects it will throw an error.
  2. .empty? returns true, if the string/array/hash has length = 0, aka “empty”. This means a string with no characters (including white spaces), an array with no items, and a hash with no keys.
  3. e.g.
a. [].empty? => true b. { key: “value”}.empty? => false c. “”.empty? => true d. “ “.empty? => false

.blank?

  1. Is actually a custom method added to the base object by the Rails team and subsequently, can only be used in the context of rails.
  2. .blank? returns true, if an object is nil, false, a whitespace character only, or is empty?
  3. Basically this allows you to do .nil?, and .empty? call at the same time, and for strings check also check for white spaces.
  4. e.g.
a. “ \n“.blank? => true b. [].blank? => true c. nil.blank? => true d. “hello world”.blank? => false

.present?

  1. present?, like .blank? is a creating of rails and can only be used in the context of Rails.
  2. .present? is simply !.blank?
  3. e.g.
a. “ \n“.present? => false b. [].present? => false c. nil.present? => false d. “hello world”.present? => true

if conditions

  1. Often we write code like if(myVar) and implicitly check the truthiness of the variable. This can be especially confusing since many developers write similar code in different languages but it act differently for each language.
  2. For ruby a falsy value is nil or false . All other values are true.
  3. e.g.
a. if (false) => false b. if (true) => true c. if (nil) => false d. if (“”) => true e. if ([]) => true

TLDR:

So in summary here are the concepts that are important to remember:

  1. .nil? is available on ALL objects
  2. .blank? and .present? are ONLY available in Rails. Dont try using these in other non-Rails projects.
  3. .nil? checks if an object is nil
  4. .empty? is available only on string, array and hash, and checks if the length = 0.
  5. .blank? returns true, if an object is nil, false, a whitespace character only, or is empty?
  6. .present? is the opposite of .blank?
  7. if conditions are false if they are nil or boolean false, true otherwise
  8. A string of only whitespace characters returns false for .empty? and true for .blank?

Also, here is a completely original reference table that summarizes all the use cases.

Anyways hopefully this helps people remember what each does and when to use each function if you already hadn’t read one of the many other blog posts on this topic!

Extra: Tips / Gotchas

  1. FixNum 0 is truthy. This might be confusing to those coming from JavaScript where 0 in a if condition evaluates to false.
  2. !myVar.nil? is not equivalent to myVar . Though this is typically true, this is not the case for boolean values. If myVar = false, then !myVar.nil? evaluates to true, and myVar = false.
  3. .blank? can be used on all objects in Rails even though it doesn’t always makes logical sense. For example, if i create a custom class MyClass, in rails, then MyClass.new.blank? is available even though my class might not have any concept of blank? or empty?. So this can be kind of confusing, and I like to keep my usage of .blank? to mainly strings and checking .nil? || .empty?.
  4. 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:
a. [ nil, ‘’ ].blank? == false b. [ nil, ‘’ ].all? &:blank? == true

Extra: Still want more information?

Looking at the source code and seeing exactly how things are implemented can help solidify the information and understanding of how things work.

.nil?

Nil has a super simple implementation. Basically if the object’s type is NilClass, .nil? it returns false. All other objects simply return true. No logic at all!

nil? implementation for the NilClass

static VALUE
rb_true(VALUE obj)
{
return Qtrue;
}

nil? implementation for Object

static VALUE 
rb_false(VALUE obj)
{
return Qfalse;
}

.empty?

We mentioned earlier that empty? is checking to see if the length == 0, and you can see from the implementations of empty for array, string, and hash, this is an accurate description!

.empty? implementation for array

static VALUE 
rb_ary_empty_p(VALUE ary)
{
if (RARRAY_LEN(ary) == 0) return Qtrue; return Qfalse;
}

You can see that the code is very straightforward. If the array’s length equal zero then return true. Here RARRAY_LEN is a macro that gets the length of the array.

.empty? implementation for string

static VALUE 
rb_str_empty(VALUE str)
{
if (RSTRING_LEN(str) == 0) return Qtrue; return Qfalse;
}

Again, you can see that the code is very straight forward and essentially identical to Array’s implementation of empty?. If the string length equals zero then return true.

.empty? implementation for hash

static VALUE 
rb_hash_empty_p(VALUE hash)
{ return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)

Here we see a slightly more abstract implementation where there is a macro RHASH_EMPTY_P that checks if the hash is empty. But if we look at the implementation of RHASH_EMPTY_P we see that its exactly like array and string where it checks if the size (or length) is equal to zero.

So we just confirmed that the description for empty? as checking the length equals 0 is pretty much 100% accurate! No gotchas here.

.blank?

Unlike .nil? and .empty?, .blank? is implemented completely in ruby. There is a general implementation of .blank? on the Object class, but this is overridden by more specific implementations for NilClass, FalseClass, TrueClass, Array, Hash, String, and Numeric. Let’s take a look.

NilClass and FalseClass

Both these classes always evaluate to true. You COULD make the argument that False ( like 0) shouldn’t be considered blank, since it does have some value.

def blank? 
true
end

TrueClass and Numeric

TrueClass and Numeric are always false. That is why even 0.blank? is false.

def blank? 
false
end

Array and Hash

For array had hash, .blank? is just an alias for .empty?

alias_method :blank?, :empty?

String

String has the most “complicated” implementation. Basically the string is checked against a regular expression to see if its made up of all whitespace.

BLANK_RE = /\A[[:space:]]*\z/ 
def blank?
BLANK_RE === self
end

Object

This is the default implementation for all other objects. Basically if the object has an empty? method, it delegates to that, otherwise it checks if the object is nil or not.

def blank? 
respond_to?(:empty?) ? !!empty? : !self
end

That’s everything for blank! You can now clearly see how blank? is implemented in rails. Since we know that blank? uses empty? if its available, we can create custom classes that implement empty?, and blank? will automatically use that method. Also we can see that the implementation of blank? using alias_method for array and hash is actually redundant. Object’s implementation of blank? already calls the .empty? method if it exists, so there is no need explicitly alias blank? to empty?. Maybe the rails team did this for the slight performance gain or improved understandability of their code? I don’t know

.present?

.present? has the simplest implementation, which doesn’t require much explanation. Its simply the opposite of blank.

def present? 
!blank?
end

Final Summary

Anyways that’s it for our tour into Ruby and Rails implementation of .nil?, .empty?, .blank?, and .present?. As you can see all the implementations are very straight forward and hopefully should help you remember what each of them do!

I can’t believe you made it this far. Thanks for reading!

If you enjoyed this post and thought it was interesting please take a second to recommend or share it with your friends! ☺

Originally published at blog.bottega8.com on August 26, 2014.

--

--

Haji Furukawa
Bottega8 Posts

Co-founder Bottega8 LLC. We build web apps that moves your business forward. Techie, Skier, Runner.