« Back to Blog

What Comments Say About Your Code

By Ryan Veazey
Jul 9, 2018

Commenting code is generally considered to be a good thing. It’s always nice to help explain what you’re doing for future reference. However, there are many cases where the need to comment some piece of code may reflect some code that needs to be rewritten.

Below are a few different types of situations where your comments may be supporting code that could be better.

Examples of Bad Comments

Commented Out Code

The simplest example is one of those things that’s fine to do locally, but shouldn’t be committed.

user = User.new
# user.validate!

Here it’s pretty obvious that we’ve commented out a line of code. There are any number of reasons to do this and they are fine. What’s not fine is having this end up in version control. If the line needs to be deleted, delete it. It will be in version history and can come back. Leaving it commented out will leave future developers confused as to whether or not it should be deleted or uncommented.

Redundancy

Another simple example is the useless comment:

user.first_name = "" # set the user's first name to empty

This comment is providing nothing whatsoever that the code doesn’t make immediately clear.

The rest of the examples are being used to hide bad or less-than-ideal code.

Cryptic Names

Sometimes comments are used to explain bad variable or method names:

"#{x.capitalize} #{y.capitalize}" #First Last name

It would be much better to simply name the variables what they are and omit the comment.

"#{first_name.capitalize} #{last_name.capitalize}"

Unclear Goals

Some things are much easier to explain than to code. While the following example doesn’t take a long time to understand, it’s far more complicated and procedural than it needs to be:

target_user = nil
users.each do |user| # find user by id
if user.id == id
target_user = user
break
end
end

Many languages have libraries and features which can greatly reduce the effort needed to understand the code. For example, the above code could be written much more simply:

target_user = users.find { |user| user.id == id }

We’ve almost rewritten the comment as code. This will depend on the language and its idioms, but many have some powerful tools to help make code clear, such as Python’s list comprehensions, C#’s LINQ, or any language with a rich set of higher order functions on collections.

Giant Functions

Again, this will differ based on language, but sometimes a function is simply too big. Sometimes it can be much shorter, but anything over a screen tends to be a strong candidate for breaking up into smaller, descriptive functions.

By using clear, descriptive names helper functions and properties, we can often eliminate the need to explain them in comments.

Magic Numbers

Sometimes we need to have some literal values (often numbers) in the code.

if order.status == 4 # disabled

Here the comment is explaining that a status of 4 is a disabled status. A much better approach would be to create a constant or something like an enum to codify this.

DISABLED_STATUS = 4
...
if order.status == DISABLED_STATUS

Of course, this constant could also be scoped to a specific type or put into some sort of status collection map. Another option for situations like this might be to declare a boolean property on the class.

if order.disabled?

Good Comments

As a general rule, comments should

1) Explain why (or occasionally how) rather than what. 2) Be clear and concise — complete sentences are not required. 3) Be specific. Try to avoid ambiguous terms. 4) Add information that’s not already in the code.

When in doubt, it’s better to leave a comment than to omit one, but taking the time to look over comments before you commit can help create a cleaner, clearer codebase. I have also written some other helpful blog posts about tips for new Mac users, best file-naming practices, error reporting and read-eval-print loops.