The following blog post is adapted from material found in my new book, "Easy Active Record for Rails Developers". Among many other topics, you'll learn about model generation, migrations, validations, associations, scopes, joins, includes, forms integration, nested forms, and model testing with RSpec and FactoryGirl. The book is slated for release in early June. The book is now available, head over to this website's home page to learn more.


Back in the 90’s I lived for a period of several years in southern Italy. When I first arrived, I knew little more than ciao and grazie, meaning learning Italian was a real priority in order to land a job and successfully integrate into society. Within about six months I’d become fairly fluent, although like anybody who is relatively new to a language I was prone to occasionally making the hilarious (to native speakers, anyway) gaffe. The one episode that really sticks out was the day I was grilling out with some friends at a park when I watched a rabbit scamper under some brush. Apparently at the time I must have thought this was a pretty rare event, akin to seeing Bigfoot, because I turned and blurted out, “Ho visto un coglione!” After a moment of confusion, my friends soon broke down into tears laughing, as I had mixed up coglione (testicle) with coniglio (rabbit).

The Definition of Nothing is a Matter of Perspective

It’s similarly easy to confuse terms when working with a programming language, although the consequences will probably not be as comical. When working with Ruby and Rails, one of the most commonplace sources of such foul-ups stems from mixing up the nil?, blank?, and empty?. All three methods clearly deal with determining whether a data structure is assigned a value, but there are different degrees of nothingness, and in the world of programming those degrees are important. For instance, you might wish to know whether a string is assigned nothing in the sense it has been assigned zero characters, or assigned nothing in the sense it consists solely of whitespace. When examining an object you might like to know whether the object is nil, or simply does not exist (meaning it has not been assigned any value whatsoever of any sort). But if you look up the definition of nil, you’ll learn it means zero, or nothing. So isn’t that what we’re trying to ascertain when we want to know whether a string contains zero characters? Not exactly, and it is precisely these nuances that are the cause of so much confusion when it comes to these methods.

The best way to remove any future confusion is to take a few moments to really instill the differences through a series of examples (and perhaps bookmark this post for future reference). So let’s spend the rest of this post working through a number of different situations.

Does an Array, Hash, or String Contain Any Characters at All?

If you’re only goal is to determine whether a string has been assigned any characters whatsoever, including whitespace, then you’ll always want to use empty?. Let’s fire up the Rails console and work through a few examples:

$ rails console --sandbox
>> 'Space Invaders'.empty?
=> false
>> ''.empty?
=> true
>> ' '.empty?
=> false
>> "\n".empty?
=> false

The outcome of the very first example is obvious; The string Space Invaders is clearly not empty, therefore false is returned. You’ll need to pay a bit more attention to the next three examples however, because each illustrates an important aspect of empty?. The second example involves a string containing no characters at all, including whitespace, therefore it is indeed empty (true). The third example contains a single whitespace character, therefore empty? returns false. The final example contains a Ruby escape sequence, therefore it too is false.

The second example in particular provides ample opportunity for a new Ruby developer to be steered in the wrong direction, because while the string is indeed empty, it is not nil. Consider what happens when you use nil? in conjunction with an empty string:

>> ''.nil?
=> false

It returns false, because blankness isn’t equal to nonexistence!

Does the Object Appear to be Blank?

If your evaluation requirements are less stringent in that you would only like to know whether the data structure has the appearance of being empty, then you’ll use the (Rails-specific) blank? method. Therefore, the appearance of being empty could mean the structure has been assigned nil, whitespace characters, or in the case of an array or hash, contains no elements. Let’s return to the Rails console and consider a few more examples:

>> [].blank?
=> true
>> ['Zaxxon', 'Gorf'].blank?
=> false
>> '  '.blank?
=> true
>> "\n\r\t".blank?
=> true
>> nil.blank?
=> true
>> l = Location.new
=> #<Location id: nil, name: nil, description: nil>
>> l.blank?
=> false

Again, the devil is in the details. The outcome of the first two examples should be apparent, because in the first the array contains no values and therefore true is returned, and in the second the array contains two values and therefore false is returned. In the third example however the string consists of whitespace, but it gives the appearance of being blank and therefore true is returned. In the fourth example the string clearly consists of several characters, however those are escape characters and therefore when rendered they would again give the appearance of being blank, meaning true is returned. In the fifth example, nil is the very definition of nothing, and therefore it too is blank. And in the final example, we first created a new object of type Location, which contains several attributes and is therefore not blank.

Incidentally, the present? method returns true if an object is not blank. Therefore, the following two statements are equivalent:

>> !['Zaxxon', 'Gorf'].blank?
=> true
>> ['Zaxxon', 'Gorf'].present?
=> true

Using the nil? Method

The Rails-specific nil? method documentation nicely summarizes the method’s behavior, stating: Only the object nil responds true to nil?. What does this mean? It means true, false, 0, '0', "Ikari Warriors", {}, and anything else except for objects of type NilClass will return false when evaluated with the nil? method! Return to the Rails console one more time and work through the following examples:

>> true.nil?
=> false
>> false.nil?
=> false
>> nil.nil?
=> true
>> nil.class
=> NilClass
>> 0.nil?
=> false
>> "Ikari Warriors".nil?
=> false
>> ''.nil?
=> false

In Summary

Ruby and Rails provide several choices for surveying the various levels of nothingness; just be sure to choose the proper approach and avoid a programming faux pas!


Like what you read? There’s plenty more where this came from in my new book, “Easy Active Record for Rails Developers”!

Comments