#---Nil---
nil in Ruby represents “nothing” or “no value”.
It’s Ruby’s way of saying “this thing is empty” or
“this thing doesn’t exist”.
It’s similar to null in other programming languages.
x = nil
p x # => nil
nil is an object. It’s the only object of the class
NilClass.
p x.class # => NilClass
It’s falsey in conditional statements (along with
false).
if x
p "x is not nil"
else
p "x is nil"
end
## => "x is nil"
You can check for nil using either .nil? or
comparing with nil.
p "x is NOT nil" if x
p "x IS nil" if x.nil? # => "x IS nil"
p "x is still nil" if x == nil # => "x is still nil"
nil is not the same as any of these:
an empty string (""), zero (0), an empty array,
([]) an empty hash ([]), or an empty object.
(So be careful when you compare any object with nil.)
p nil == '' # => false
p nil == 0 # => false
p nil == [] # => false
p nil == {} # => false
p nil == Object.new # => false
But nil is nil. So you can compare 2 variables
that are nil.
y = nil
p x == y # => true
When you try to access a hash key that doesn’t exist,
you get nil.
h = {a: 'aa', b: 'bb'}
p h[:a] # => "aa"
p h[:c] # => nil
(If you want it to blow up with an exception saying
there’s no such key, you must use fetch)
p h.fetch(:c)
## => 💥 blows up with:
## key not found: :c (KeyError)
When you access an array index that’s out of bounds,
you get nil:
arr = [11, 22, 33]
p arr[2] # => 33
p arr[3] # => nil
p arr.fetch(3)
## => 💥 blows up with:
## index 3 outside of array bounds: -3...3 (IndexError)
In Go, there’s a concept called “zero-value”.
If you declare a variable and give it no initial value,
then a default value based on its type is assumed.
int variable, it’ll be 0string, it is "" (an empty string)bool, it is false. And so on.In Ruby, we can get something like that with
the nil.to_* helper methods.
p nil.to_s # => ""
p nil.to_i # => 0
p nil.to_f # => 0.0
p nil.to_a # => []
p nil.to_h # => {}
p nil.to_json # => "null"
p nil.to_yaml # => "---\n"
Sometimes, nil seeps into an array or a hash.
But you might not want it. You most likely only want the
non-nil items in the array/hash.
arr = [11, 22, nil, 33, 44, nil]
h = { a: 'aa', b: nil, c: 'cc' }
You can get them with compact.
p arr.compact # => [11, 22, 33, 44]
p h.compact # => {a: "aa", c: "cc"}
Note that the original array and hash are unchanged.
.compact only returns a new array/hash with nils
removed.
Use .compact! to remove nils even from the original
variables.
arr.compact!
p arr # => [11, 22, 33, 44]
For an object to successfully respond to a method, it should first know about it.
name = 'john wick'
p name.upcase # => "JOHN WICK"
If you call a method that the object does not know about it, Ruby will scold you.
name = nil
p name.upcase
## => 💥 blows up with:
## undefined method 'upcase' for nil (NoMethodError)
And if that object is nil,
you can avoid the exception by using the
safe navigation operator &.
It will return nil instead.
p name&.upcase # => nil
Use this functionality with care. In the example above,
it is okay to use &. only if it’s okay for name to
be nil.