Matthew Boston

When to Extract Constants

Often times I see programmers get a little “Extract Constant” happy. Here, I will discuss some of the scenarios in which I believe it is okay to use constants and when it is not okay to use constants.

Consider the following:

class Greeter
  HELLO = "Hello"

  def self.greet(name)
    "#{HELLO}, #{name}"
  end
end

This is a simple and contrived example but you get the point.

Why extract constants which are merely strings of the same name? Extracting the HELLO constant provides no extra information or insight into the value.

Understandably, one could argue in favor of reuse. If our greeting needs to change from “Hello” to “Guten tag”, we have one spot to do so. But then again, would a constant with the name HELLO really make sense now if the value is “Guten tag”? I’m suggesting that it does not, and everywhere that references the constant HELLO should be changed to GUTEN_TAG; totally nullifying the argument for reuse and maintenance simplification.

So, when should we use constants?

class Today
  WEDNESDAY = 3

  def self.wednesday?
    Date.today.wday == WEDNESDAY
  end
end

You see, extracting the value 3 into a constant, giving it a name, helps give some meaning to an otherwise magical 3. Checking for ==3 all throughout our code gives us no insight into what we’re actually testing. Using the term WEDNESDAY gives us some context.

Values, that are constant in the domain, also make great constants.

class Earth
  DISTANCE_TO_THE_MOON = 238_900

  def self.time_to_the_moon(velocity)
    DISTANCE_TO_THE_MOON / velocity
  end
end

In Summary

All in all, here are a few general guidelines I like to follow when deciding whether or not I should extract a value to a constant:

  • Code reuse and maintenance simplification
  • Provides a meaningful name to an otherwise “magical” value
  • The value is a fact of the world and never changes