Hacks Can Be Good Code Too

Writing code is, like everything in life, all about making tradeoffs. Code can be quick to write, but at the same time unreadable; it can be fast, but hard to maintain; and it can be flexible, but overly complex. Each of these factors are worth considering when writing Good Code. Complicating this is the fact that: what constitutes Good Code in one situation may not be ideal in another.

Good Code is not universally so.

It is incredibly difficult to explain why one set of tradeoffs are worth pursuing in one case but not in another, and often times reasonable people will disagree on the value of certain tradeoffs over others. Perhaps a snippet of hacky string parsing is good in one place, but not in another. Often times, the most significant cost of solving a problem "The Right Way" is time.

When deciding whether to do something The Right Way or to cheat and simply hack something together, I often try to consider the exposure the given code will have. Consider these questions:

  • Do other systems touch this code?
  • How many developers will need to interact with it over time?
  • How much work would be involved in building out the correct approach?
  • How much work would be involved in building out the bad approach?
  • How valuable is the intended feature?
  • How much additional maintenance does the bad solution require?

Each of these answers helps me decide what kind of code I should write. These questions neglect multiple other factors (e.g. performance, readability), but they are a good starting point.

In a recent example I needed to modify the blog engine that powers this site as well as a few others. I wanted a simple feature that would count the number of articles on the side as well as the total number of words in every blog post, and display those values on the home page. As I've said before the blog engine for this site is very old, and has been rewritten several times. It's well beyond needing a massive rewrite, but that's not something I really want to do right now.

The blog engine is written in Python, provides a command-line interface, and uses Git Hooks both client and server-side to build and deploy itself.

I originally considered writing this feature in Python: counting the number of words in each article, adding a new context variable to the template rendering process, and then rendering the pages as normal. But that would require touching substantial pieces of the codebase (some of which I no longer understand). It would probably take me all evening to dive into the code, understand it, make the change, and test it. To be honest, this feature was not worth wasting an evening on. So I decided to just hack something.

As I said, I use Git to deploy the site. So I just added a new line to the HTML template:

    This site contains {+ARTICLE_COUNT+}
    different writings and {+WORD_COUNT+}
    total words. That's about {+PAGE_COUNT+}

And then I added a new step to the pre-commit hook that runs after the template rendering process, but before the changes are committed and the site is deployed.

WORDS_N="$(find archive/ -name "*.md"|xargs -I {} cat {} | wc -w)"
WORDS=`printf "%'d" $WORDS_N`
ARTICLES=`printf "%'d" $(find archive/ -name "*.md" | wc -l)`
PAGES="$(( WORDS_N / WPP ))"

cp ./index.html $TMP_HOME
cat $TMP_HOME |
    sed "s/{+ARTICLE_COUNT+}/$ARTICLES/" |
    sed "s/{+PAGE_COUNT+}/$PAGES/" |
    sed "s/{+WORD_COUNT+}/$WORDS/" > ./index.html

Let's check in and see how this hack fit my criteria above:

Do other systems touch this code? No
# of Developers? 1
Time for Correct Approach? 2-3 hours
Time for Bad Approach? 10 minutes
How Valuable is the Feature? Very
Additional Maintenance Burden? Not much

Is this elegant: absolutely not. Did it take basically zero time? Yes. Have I thought about it since? Not until writing this post. Would I have done this on a team project or a commercial product? Absolutely not. It's a feature for my personal blog engine and a feature that is specific to one particular low-value site that I run.

In this case, a hack is an example of Good Code. That's because Good Code is a relative construct.

Filed under: programming, software development
Other Links: RSS Feed, JSON Feed, Status Page →