Is it nil?
What is actually happening under the covers in Ruby when you ask if a variable is nil? It turns out that it's way simpler than you may think, and it all comes down to object oriented programming and inheritance.
You've probably heard it said that everything in Ruby is an object... this includes the objects that you make but also the built in objects such as Fixnum
, Float
, Time
, String
, etc. All objects in Ruby, whether they come with the language or whether it is one that you create, extend from a special built in class called Object
. This class brings with it a set of functionality, one of those methods being the nil?
method.
Object.methods.grep(/nil/)#=> [:nil?]
So let's go take a look to see what this nil?
method actually does. To do that we're going to look at the Ruby source code which is written in C.
static VALUErb_false(VALUE obj){return Qfalse;}rb_define_method(rb_mKernel, "nil?", rb_false, 0);
What this code is saying is basically that when you call the method nil?
, what you are basically doing is calling a method that is an alias of the value false
... it simply returns the value false
no matter what.
5.nil?#=> falsefalse.nil?#=> false"nil".nil?#=> false
So what is nil
then? The only thing that is nil
is nil
itself. When you use the nil
keyword in Ruby, what you're actually getting is the singleton instance of the NilClass
class.
nil.class#=> NilClassnil.class.ancestors#=> [NilClass, Object, Kernel, BasicObject]
NilClass
is a child of Object
which happens to override its parent's version of the nil?
method to have it return true
. We can see this by looking again at Ruby's source code:
static VALUErb_true(VALUE obj){return Qtrue;}rb_define_method(rb_cNilClass, "nil?", rb_true, 0);
If we were to define our own version of Object
and NilClass
, the nil?
methods would simply look like this:
class Objectdef nil?falseendendclass NilClass < Objectdef nil?trueendend1.nil? #=> falsenil.nil? #=> true
Concluding thoughts
There is only one thing that is nil
, which happens to be nil
itself.