The WegoWise team spends a lot of time talking about names. We try to pick variable, class and method names that express not only the function but also the intention of code. The idea is that good names help other developers by:
- Helping them reason about the code at a high level. Good names combined with short methods should approach the readability of pseudocode.
- Reducing the need for extra comments, which tend to get out of sync with code.
- Clarifying the purpose of an object. Sometimes if you can't find a good name for something it's because it's trying to do too much or is otherwise ill-conceived. Sometimes a good name will suggest other objects to create.
We will often suggest alternate names to each other during code review. It is also common for a developer to try out a couple names in the developer chatroom before settling on one.
This is the tale of one such occasion. Note that this is an incredibly trivial example, but it's meant to demonstrate the discussion process we use to arrive at a good name.
I was pairing with another developer on a design that let you attach arbitrary
traits to a record. We had a bit of code that checked to make sure that a value
was present, defined as not nil
and not an empty string. 0
was a valid
value. Active Support's .blank?
wouldn't work because it detects 0
as well
as ''
and nil
. In Rails this is normally less of an issue because you're
usually working with a string field or an integer field, but in our case we
had a string field that could be coerced to different types.
The code looked like this:
This would probably be good enough if we were using it in one place, but we
were using this logic in a couple places, so we thought we should encapsulate
it in a method. Also, even though this logic is certainly clear as to what it
does, it's slightly mysterious as to why it's doing it. Nothing terrible, but
it might cause a developer to slow down for a second and wonder, "What's so
special about nil
and ''
? Why didn't they just use .blank?
" A second that
could be spared with a good, explanatory name.
So we asked around in the chatroom. Here were a couple suggestions of greater and lesser absurdity:
.not_nil_or_empty_string?
.present_but_not_false_and_blank_but_not_empty?
.peanut_butter?
.nathans_choice?
.has_value?
I think it's safe to filter the list of candidates down to the first and last
options, .not_nil_or_empty_string?
and .has_value?
. The first one has the
virtue of describing exactly what's going on, but of course it's rather silly,
since the method name is almost the same as the expression it contains. The
second one is better but it reverses the question and clashes with a method on
Hash
that takes an argument.
At this point one of the developers (the same one who suggested
.peanut_butter?
actually) suggested .missing_value?
. He pointed out that
this method name expressed the intention of the code. Specifically we were
asking, "Does the field not have a usable value? Is it missing a value?" This
name exposes an additional flaw in the silly name above: that name told the
developer too much about the implementation of the method. Another developer
should only have to know about the criteria used to determine validity if it
directly concerns the problem they're working on. For most cases it's enough to
know that the field validates against "missing" values.
As noted above, this is a trivial example. It may seem like it was a waste of time to discuss this as a group, but in all it took about 10 minutes to work through the options. Because finding good names is part of our discipline as a group, our codebase as a whole is easier to understand and reason about than it would be otherwise.