One practice that I internalized a long time ago but that I still see a lot of experienced developers ignore is habitual . Most applications have common strings that are used in a number of places. These should pretty much always be stored in constants (however your language of choice implements them) rather than appearing as string literals anywhere other than when they are initially assigned. For example, a blog publishing tool might have a status field for posts with possible values of “published”, “draft”, and “scheduled”.
If you’re writing Java, you might write code like this:
blogPost.setStatus("published");
and
if (blogPost.getStatus().equals("published")) {
// do stuff }
The reason this is bad practice (even though it works like a charm) is that it costs you an opportunity to let the compiler do work for you. Let’s say you write your code like this:
public static final String STATUS_PUBLISHED = "published";
blogPost.setStatus(STATUS_PUBLISHED);
if (blogPost.getStatus().equals(STATUS_PUBLISHED)) {
// do stuff
}
If there’s a typo in that code, the compiler will catch it for me. Typos in string literals are the cause of a huge number of difficult to diagnose bugs, and are easy to avoid. There are other advantages to this approach as well, especially if you use an IDE like Eclipse. If put a string in a constant, I can use the “References” feature in Eclipse to show me every spot in my code where the constant appears. In a couple of seconds, I can discover every place in my application where the status of a blog post is set to “published”. There are all sorts of other advantages as well, like being able to rename the constant using the rename variable refactoring in the IDE as opposed to search and replace.
This practice is on my mind this week because I finally bothered to learn about Ruby constants, which are incredibly easy to declare and enable me to apply the same practice that I always use when programming in Java.
To create the same constant in Ruby, you’d just type:
STATUS_PUBLISHED = "published"
You can, of course, reference it by name, and if it’s declared in a class called BlogPost
, you can reference it like this:
if status == BlogPost::STATUS_PUBLISHED
# do stuff
end
Ruby will happily show you an error message if you reference that constant without declaring it first, so even though Ruby is looser in terms of variable declarations than Java, the compiler will still help you out in situations like this.
PHP also has constants but in my opinion the declaration syntax makes them a pain to deal with. (I still use them when I’m programming in PHP, though.)
October 12, 2006 at 12:50 am
Hi Rafe,
I totally agree that constants should be used, but I suggest reversing the order of the objects in your test…
Instead of blogPost.getStatus().equals(STATUS_PUBLISHED), use this safer variant:
STATUS_PUBLISHED.equals(blogPost.getStatus())
This way you can’t get a NullPointerException if getStatus() returns null and you try to call equals on it… your constant is never null, so it’s safe.
October 12, 2006 at 1:27 pm
Ditto for any comparison. Always put the constant value before the variable:
if( null == foo) { .,. if( 7
April 21, 2008 at 10:47 am
Give me three reasons why we should use constants instead of literals.
December 22, 2008 at 2:40 pm
Reasons to use constants in leu of literals:
if (STATUS_READY == status)
stands out more and means more thanif ("ready" == status)
.STATUS_READ
would be caught by the compiler. The misspelled literal"read"
would happily compile and becomes a runtime bug.