Ruby: Nil

Following my previous posts with basic Javascript aspects, like context and variable hoisting, I’ll try to write some basic concepts of the Ruby language. I decided to start with something that usually confuses new Ruby users (sometimes they don’t even know that they are confused, by the way): the Ruby nil object.

In Java we’re used to treat null as a special value or even a keyword. In Java, null holds a value which no valid point will ever refer to. So, we usually do comparations like this:

if (person != null) {

Well, we have to check if if the object really exists, i.e., if it points to something that isn’t null. Invoking methods in a null object will throw the commonly seen NullPointerException, which, according to my college professor, is a programmer mistake, always.

Anyway, in Ruby, there is also a way to check if an object is null, or, more specifically, nil:

unless person.nil?
# or with inline conditionals:
person.walk unless person.nil?

What the heck? We just invoked a method in a possibly nil object? Yeap. That is possible due to a really neat implementation of the Null Object Pattern. Basically and grossly, instead of having a null reference to convey absence of an object (like our non-existent person object), the language uses an object with some useful methods, but no real behavior (for example, Ruby will not automagically create a NilPersonClass (as the pattern itself suggests) with all your method signatures with no implementation).

Actually, nil is a singleton instance of the NilClass1, and, as you can see, this class extends Object and both of them implements the method nil?, while only the NilClass implementation of nil? return true.

So, we can call nil? in any object, and, in Ruby, everything is an object, so, we can call nil? in everything:

nil.class # NilClass
10.nil? # false
nil.nil? # true
nil == nil # true

Also following a similar behavior, we have the true and false statements, which are singleton instances of TrueClass and FalseClass respectively.

Related Posts

Writing cli applications with Golang

Measuring production code coverage with JaCoCo

From Travis Enterprise to BuildKite in 50 repositories