Zero, Blank, and Nil
Tuesday, November 14th, 2006Back in the bad old days of web development, I used JSP to create page content. Java is a terribly language for doing front-end web work, because it’s bad at processing text, and which usually comprises the majority of what web apps do. (And that’s also why Perl was the reigning king in this realm for so long.)
One of the things that drove me absolutely batty about JSP was the need to check every string for both null and blank, which meant your code was littered with stuff like:
if (request.get("quantity") != null && request.get("quantity") != "")
{
quantity = (int)request.get("quantity")
doSomething(quantity);
}
Yikes. When I moved on to PHP, I was immediately struck by the improved readability of the same code:
if (strlen($quantity) > 0)
doSomething($quantity);
An empty string and a null will both give you zero on a string length. (You can always use === or isset() if you want to check for null explicitly.) A similar guard clause if often used for integers and arrays, too. In Java you have to check both whether a value is null, and whether it is zero or empty, respectively. In PHP you can just do:
if ($quantity != 0)
and
if (!empty($array))
Now that I’m living in Ruby land, I’ve found that my code is generally much prettier than PHP for most things… except this one. Ruby is a bit more strongly typed that PHP, so I’m back to the JSP syntax:
if params[:value] != nil and !params[:value].empty?
Hardly the succinct readability one has come to expect.
Ruby’s base classes provide some nice convenience functions to make your code more readable: Array.empty?, String.blank?, and Fixnum.zero?. The solution here seems obvious: make all of these methods exist on NilClass.
Thanks to Ruby’s metaprogramming, it’s easy to add this to your own application:
class NilClass
def empty?; true; end
def blank?; true; end
def zero?; true; end
end
Great! Now we can just do:
if params[:value].empty?
Furthermore, I would tend to think that all of these should be collapsed together into a single method. I think empty? is the most applicable. So empty? means a blank string, a zero, or an empty array or hash. This reflects what the code really wants to know: is there anything in this variable? Should I bother doing anything with it? 95% of the time, the difference between nil and non-nil but empty is irrelevant.
Update: aidanf suggests using .blank? instead, which I like a bit better than the names suggested above.
Update 2: A coworker informed me that Rails extends most of the basic Ruby types with blank?. So you can do [].blank?, {}.blank?, nil.blank?, 5.blank?, etc. Apparently this is pretty unknown, because not one person mentioned it in the many dozens of comments on this post appearing on various news aggregators. Note that 0.blank? does return false, but in most cases I’m more interesting in strings anyway.