---
title: Let Your Code Speak For Itself
teaser: Comments are like playing telephone. Avoid them with clearer method names.
tags: web,good code
author: Adarsh Pandit
published_on: 2014-07-16
---

Let's say you have some code whose intent is clear to you but you can see a
world where someone else may be confused. Often after writing such code, you
realize this and add some comments to clarify the intent.

We add code comments for other developers who will interact with whatever we
wrote, because we are courteous and thoughtful teammates:

```ruby
class HostsController < ApplicationController
  def show
    # make sure user belongs to host if name is internal
    # set current host in session

    if current_user.hosts.include?(host) && host.match(/intranet.example.com/)
      session[:current_host_id] = host.id
      redirect_to(projects_path)
    else
      raise 'something went horribly wrong oh nooooo'
    end
  end
end
```

## The Telephone Game

Remember [the telephone game]? Messages passed through intermediaries
can get garbled in transmission. Particularly unreliable, logic-free
intermediaries like code comments.

On their face, comments should be super helpful - I mean, you've left helpful
notes for the next person! Isn't that a good thing?

Yes, although now we have duplication - the comment and the code itself both
speak to what this bit of logic should do.

Comments are a code smell which means "something _may_ be improved here and we
should dig deeper to see if that's true." In this case, the smell is "hey
something is probably more complicated than it needs to be."

Later on, when someone moves the session-setting behavior somewhere else, they
have to remember to move this comment or update it. As humans, this is easy to
forget.

Instead, let's use intention-revealing method names to encapsulate the behavior.
We'll also move this logic into private methods since we don't want other
classes calling these methods:

[the telephone game]: http://www.wikihow.com/Play-the-Telephone-Game

```ruby
class HostsController < ApplicationController
  def show
    if user_belongs_to_host? && host_name_is_internal?
      set_current_host_in_session
      redirect_to(projects_path)
    else
      raise 'something went horribly wrong oh nooooo'
    end
  end

  private

  def user_belongs_to_host?
    current_user.hosts.include?(host)
  end

  def host_name_is_internal?
    host.match(/intranet.example.com/)
  end

  def set_current_host_in_session
    session[:current_host_id] = host.id
  end
end
```

## Other Smelly Comments

* TODOs, like `# Remember to fix this terrible method`
* Commented out dead code. Just delete it - that's what Git is for.
* Comments which restate the method name in English.

Comments are one of the code smells we address in our [Ruby
Science] ebook.

[Ruby Science]: http://rubycience.com?utm_source=giantrobots&utm_medium=blog&utm_campaign=code_comments_post

## When Are Comments Useful

This isn't a hard and fast rule. Some comments are useful:

* Class-level comments: Adding a comment at the top of a class to describe its
  responsibilities can be helpful.
* Open-Source: Ruby Gems and other open-source libraries are good places to add
  more detail, because we can use tools such Yard to automatically generate
  documentation from the comments. Here's [an example] in Paperclip. If you're
  providing a library for others to use, lightly commenting the public interface
  is typically encouraged so that documentation for the library can be
  auto-generated. [Here's an example in Go].

[an example]: https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/attachment.rb#l7-l9
[Here's an example in Go]: http://golang.org/doc/effective_go.html#commentary
