Double Negatives

Erica Kastner · January 27, 2009

Recently I was working on a project adding new functionality that would queue a long-running task to a background job. The original code looked something like this:

receive_data
forward_data

My task was to run enqueue_data instead of forward_data since the forwarding was taking too long. I wanted to retain the ability to run forward_data if a specific parameter was passed in. Since I was creating a parameter that would override a default feature, my first intuition was to name this parameter “noenqueue”:

receive_data
if params['noenqueue']
  forward_data
else
  enqueue_data
end

I then smacked myself in the forehead when I realized I had “pulled a Microsoft.” I had created a setting that is named such that setting it to true would disable a feature, while setting it to false would enable the feature. You see this all the time in Microsoft products.

It irritates me because you have to think in double-negative terms when setting the parameter. Instead, it is much more intuitive to create settings that are positive - that setting them to true will enable something.

Lesson learned: I renamed the parameter to “forward_immediately”:

receive_data
if params['forward_immediately']
  forward_data
else
  enqueue_data
end

One good syntactic feature of Ruby is the unless keyword. I prefer to use “unless variable.nil?” instead of “if variable” if I want to only operate on non-nil objects. I find it a bit more intuitive.

unless document.nil?
  document.write
end

However, you can still get into trouble when you need to branch:

unless document.nil?
  document.write
else
  document.new(str).write
end</pre>




An else branch on an unless is, in my opinion, the least readable or intuitive way to write branches.