# 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).

```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?`
    

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

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

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

For example,

```ruby
# 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,

```ruby
# 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)
```

```ruby
# rails console
$ nil.blank?
#=> true
```

### 3\. `nil` and `!` , `!!` operator

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

```ruby
$ !nil 
#=> true

$ !!nil
#=> false
```

### 4\. `nil` and Ruby if modifier

The syntax of Ruby `if` modifier looks like:

```ruby
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,

```ruby
$ 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

* [https://www.amazon.com/Practical-Object-Oriented-Design-Ruby-Addison-Wesley/dp/0321721330](https://www.amazon.com/Practical-Object-Oriented-Design-Ruby-Addison-Wesley/dp/0321721330)
    
* [https://www.rubyguides.com/2018/01/ruby-nil/](https://www.rubyguides.com/2018/01/ruby-nil/)
    
* [https://github.com/rubinius/rubinius/blob/master/core/nil.rb](https://github.com/rubinius/rubinius/blob/master/core/nil.rb)
    
* [https://www.tutorialspoint.com/ruby/ruby\_if\_else.htm](https://www.tutorialspoint.com/ruby/ruby_if_else.htm)
    
* [https://www.tutorialspoint.com/ruby/ruby\_operators.htm](https://www.tutorialspoint.com/ruby/ruby_operators.htm)
