10 January 2022
Is it greppable?
Here’s a useful question to keep in mind when seeking to write maintainable code: “is it greppable?”
Grep is the ubiquitous command-line search utility, which was the seed for a meandering conversation last week.
The purpose of the question is, if I return to this code in the future, can I find a function name, string constant, class, or variable by doing a simple grep for it? If so, then it will be easier to understand the landscape of the project and to make updates more safely. However, if I’m getting cute with metaprogramming or going over-the-top making things DRY, then I might not. In this case, I’ll have a harder time piecing the code back together and I might miss something important in a refactor. Code that’s too DRY (pun incoming) is prone to cracking.
As a trivial example, here are a bunch of similar strings in Python:
# GOOD
STATUS_ACTIVE = 'status_active'
STATUS_INACTIVE = 'status_inactive'
STATUS_TRIALING = 'status_trialing'
a well-intending, but misguided developer could take care of that shared prefix as such:
# BAD - NOT GREPPABLE
_PRE = 'status_'
STATUS_ACTIVE = f'{_PRE}active'
STATUS_INACTIVE = f'{_PRE}inactive'
STATUS_TRIALING = f'{_PRE}trialing'
While the variable names will be easy to find, if instead, someone searches for one of the strings, it could easily be missed. Furthermore the code is harder to read. In some ways, contending with this question can help offset tendencies to elegantly complicate code.
This matters a lot for dynamic typed programming languages (Python, JavaScript, Ruby, etc.) where you can’t rely on static types when refactoring or searching for references, but I think it’s helpful when writing in any language. For example, it came up in the comment discussion when I was reasoning through enums in Typescript.
Of course this isn’t a new idea, for a deeper dive—along with a look at edge cases—check out: “Grep test” by Jamie Wong.