A Healthy Respect of NullI recently traveled from the over-populated World of Java into the beautifully rustic Land of (professional) Ruby. Like any traveler, I had a few companions (ideologies, habits and conventions) which kept me safe and sound in Java's harrowing landscape. But when I left Java for newer pastures some of those companions trailed along. One of them is named Scary Null.
In Java -
nullis not an object - just ask it:
null instanceof Objectwill be false. Worse yet, attempting to use it for anything other than a place-holder and he'll throw his even scarier friend
NullPointerExceptionat you. Over the years I learned a healthy respect for
null. He has one and only one job: to hold the place of something. How dare I use
nullin a capacity for Which He Was Not Intended!
A Healthy Disrespect of NilIn Ruby Land, however, he has a cousin:
nilis not a fearful beast like
null. Nil is a charming little scamp, a first class object that does her best to help you out. This took some getting used to for me. I'm so used to writing code like this in Java:
int i = str == null ? 0 : Integer.parseInt(str);that it almost feels awkward to do it the Ruby way:
i = str.to_iIn the back of my mind I think: "Eric, what are you doing! What if 'str' is nil? I'll get an exception!" Au contraire. Since
nilis a real object, it doesn't throw exceptions -
nilis an object of the type
NilClasswhich implements plenty of useful methods, like:
nilrepresents: false. That makes code like this possible:
cis true. No exception. If I was smacked upside the head with a board and the ensuing brain damage caused me to want
nilto throw an exception in this situation, I could always override the method in
The other methods are equally kind.
nil.to_s(to string) returns "" (empty string),
nil.to_a(to array) returns  (empty array), and my favorite
nil.nil?return true - and is the only object that does.
Bring on the FunNil is fun, but so what? If I attempt to use a method that doesn't exist, I'll still get an exception! True. However, since we know that
nilis a real object, and since Ruby can override object implementations on the fly (weee!) we can also add methods to
Consider the following code, that iterates until a string is constructed that is over 10 character long, then returns the string:
laDid you see something wrong with that picture? Not if you are from the World of Java. Initialize a variable, iterate, append and finally return the value on the correct conditions. But:
Why declare a variable that we only use inside the loop and return? Why indeed. Let's try it again without declaring the variable.We get an error :(.
NoMethodError: You have a nil object when you didn't expect it!Oh - it looks like Ruby requires us to define variables first. And since
You might have expected an instance of Array.
The error occurred while evaluating nil.+
str += "la"is the same as
str = nil + "la"when
stris not yet defined, it makes sense that it complains.
But wait! Re-read the last sentence. Of course! Ruby thinks that
nil, and is attempting to append the string "la" to it. So what would happen if the
nil.+method was declared? What if it just returned whatever was passed to it?
def nil.+(o)Now we're cooking with gas! Try and run the above code now. It works(!) since our
nil.+method just set
strto "la". For each successive loop, str just uses the standard string append method instead.
There are a few methods I like to add to
nil. Just create a file named "safe_nil.rb" in your library, and add it like any requires.
Now you can safely do things like this:instead of