Hopefully somewhere in your programming career you reached a point where you could recognize the following as a Bad Idea:
Foo.Bar(42)
What does 42 represent? Why are we passing it into the Bar method? Why not 41 or 43 instead? Presumably 42 has some particular meaning in the context of the method call, but it is not obvious from the usage what that meaning is. Numeric constants which are used directly in expressions like this are called Magic Numbers, and most of us are taught to recognize them and eliminate them by creating named constants:
constant int AnswerToLifeTheUniverseAndEverything = 42;
...
Foo.Bar(AnswerToLifeTheUniverseAndEverything);
Now it is clear why we are using 42: because it is The Answer to Life, the Universe, and Everything. This makes the code much more readable. It also means that should we ever need to change the value of the constant, we only have to change it in one place, instead of hunting for the value 42 everywhere in our code and changing it to 43.
The odd thing is, though, that the same mental alarm that goes off in my head at the sight of numeric constants in expressions is curiously silent for boolean constants. That is:
Control.Invalidate(true);
For some reason, I don't immediately see anything wrong with this; but I should, because this "magic boolean" suffers from the same problems as the magic number example. What does true represent here? How does it affect the behavior of the method call, compared to passing false instead? Or, even worse:
Control c = ...;
c.SelectNextControl(c, true, true, false, true);
Yes, that is a real method. Now, I have some pretty significant experience in WinForms programming, but I can state for a fact that there is no way I can remember what each of those boolean parameters does. If I am reading through code and come across this call, and I need to know what it does, I HAVE to stop and look it up in the documentation. Yes, Intellisense might tell me, but that means that I have to stop reading, position the cursor, invoke Intellisense, and in some cases find the right overload, which isn't always trivial. That's a lot of hassle.
Do you have a mental alarm for magic booleans? If not, why not? Why do we as programmers tend to distinguish them from magic numbers? In the next post we will look at options for eliminating magic booleans.