The following is a dramatic re-enactment of an actual Command-Query Separation crime. The real entities have been replaced to protect their identities and to keep yours truly from getting pelted with a barrage of nerf bullets.
The Scene of the Crime:
This crime occurred within this seemingly innocuous piece of code that was designed to help developers cope with those nasty meetings that pointy haired bosses are always making them attend.
About 100 iterations into the while loop, the developer entity shown here threw a null reference exception and went to that garbage collector in the sky.
Although everyone initially assumed that this was yet another meeting-induced suicide, the stack trace autopsy clearly showed that the object had mysteriously been set with lethal levels of caffeine.
Forensic debuggers made the crucial breakthrough in the case after uncovering the following suspicious code snippet while running a routine ReSharper “Find Usages” command.
After intense questioning, the suspected block of code finally admitted to never having experienced an infinite loop despite having no obvious exit conditions.
This was enough for investigators to attain a warrant for the source code of the IsSleepy method, which revealed the following damning evidence.
The poor, unsuspecting developer object was injected with a shot of espresso each time the IsSleepy check was performed.
The IsSleepy method was clearly misleading clients by returning a value and thus impersonating a query method even though it surreptitiously performed an action (a.k.a. command) behind the scenes.
This is reckless violation of the classic Command-Query Separation law established by Bertrand Meyer (not to be confused with the more recent architectural level rule introduced by Eric Evans).
The unsuspecting victim didn’t have a chance.
The person responsible for this atrocity was easily apprehended with a TortoiseSVN Blame and eventually sentenced to refactor the code. The reformed code can be seen here:
The Moral of the Story:
If your method returns a value, then you should avoid performing any actions.
There are a few rare exceptions to this design rule (e.g. Stack.Pop), but this is a firmly rooted expectation on the part of API consumers and violating it will inevitably lead to frustrating Heisenbugs.
More importantly, you should never ever ever write a blog post after watching a classic episode of CSI. No good can come of it.