Understand `nil` in Ruby

Photo by Jess Bailey on Unsplash

Understand `nil` in Ruby

What's nil?

nil is an instance of NilClass. It's a special Ruby object used to represent the absence of any value. And it also behaves like false when used in a conditional statement.

What's more, there is only one nil object, whose object_id is always 8 (in 64-bit Ruby).

# irb
$ nil.object_id
#=> 8

Let's play with nil now.

1. nil and nil?

In Ruby, NilClass inherits from Object, and both of NilClass and Object define nil? method.

  • Only the object nil responds true to nil?

  • Other objects, like '' , {}, [] etc, responds false to nil?

# irb
$ nil.class
#=> NilClass < Object

$ NilClass.instance_methods.include?(:nil?)
#=> true 

$ Object.instance_methods.include?(:nil?)
#=> true

For example,

# irb
$ nil.nil?
#=> true

$ ''.nil?
#=> false

$ [].nil?
#=> false

$ {}.nil?
#=> false

2. nil can only respond to blank? in Rails.

It's common to see blank? in the codebase. However, blank? is only defined in Rails library, not in Ruby.

We can see the different results when calling nil.blank? in irb and Rails console.

For example,

# irb
$ nil.blank?
#=> Traceback (most recent call last):
#        4: from /Users/yuchu/.rvm/rubies/ruby-2.6.6/bin/irb:23:in `<main>'
#        3: from /Users/yuchu/.rvm/rubies/ruby-2.6.6/bin/irb:23:in `load'
#        2: from /Users/yuchu/.rvm/rubies/ruby-2.6.6/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
#        1: from (irb):14
#NoMethodError (undefined method `blank?' for nil:NilClass)
# rails console
$ nil.blank?
#=> true

3. nil and ! , !! operator

! and !! are the operators to make sure the values return boolean.

$ !nil 
#=> true

$ !!nil
#=> false

4. nil and Ruby if modifier

The syntax of Ruby if modifier looks like:

code if condition

if expressions are used for conditional execution. The values false and nil are false, and everything else is true.

Executes code if the conditional is true.

For example,

$ result = 'Hello'
$ note = { nickname: 'Jenny' }
$ result = 'Hello, Jane.' if nil
$ result
#=> 'Hello'

$ result = 'Hello, Jane.' if false
$ result 
#=> 'Hello'

$ result = 'Hello, Jane.' if true
$ result
#=> 'Hello, Jane.'

$ result = 'Hello, Bob.' if note[:non_existent_key]
$ result
#=> 'Hello, Jane.'


$ result = 'Hello, Jenny.' if note[:nickname]
$ result
#=> 'Hello, Jenny.'

nil seems familiar, but there is something detailed worth learning.

Organizing the note helps me to correctly understand nil. It's helpful, especially when I need to read the code fastly.


Reference