... | ... | @@ -10,16 +10,31 @@ |
|
|
|
|
|
#### F1: Too Many Arguments
|
|
|
|
|
|
Functions should have a small number of arguments. No argument is best, followed by one, two, and three. More than three is very questionable and should be avoided with prejudice. (See "Function Arguments" on page 40.)
|
|
|
Functions should have a small number of arguments. No argument is best, followed by one, two, and three. More than three is very questionable and should be avoided with prejudice. (See "Function Arguments" on page 40. Text reproduced below.)
|
|
|
|
|
|
__Function Arguments__
|
|
|
|
|
|
The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification—and then shouldn't be used anyway.
|
|
|
|
|
|
Arguments are hard. They take a lot of conceptual power. That's why I got rid of almost all of them from the example. Consider, for instance, the `StringBuffer` in the example. We could have passed it around as an argument rather than making it an instance variable, but then our readers would have had to interpret it each time they saw it. When you are reading the story told by the module, `includeSetupPage()` is easier to understand than `includeSetupPageInto(newPageContent)`. The argument is at a different level of abstraction than the function name and forces you to know a detail (in other words, `StringBuffer`) that isn't particularly important at that point.
|
|
|
|
|
|
Arguments are even harder from a testing point of view. Imagine the difficulty of writing all the test cases to ensure that all the various combinations of arguments work properly. If there are no arguments, this is trivial. If there's one argument, it's not too hard. With two arguments the problem gets a bit more challenging. With more than two arguments, testing every combination of appropriate values can be daunting.
|
|
|
|
|
|
|
|
|
Output arguments are harder to understand than input arguments. When we read a function, we are used to the idea of information going in to the function through arguments and out through the return value. We don't usually expect information to be going out through the arguments. So output arguments often cause us to do a double-take.
|
|
|
|
|
|
One input argument is the next best thing to no arguments. `SetupTeardownIncluder.render(pageData)` is pretty easy to understand. Clearly we are going to render the data in the `pageData` object.
|
|
|
|
|
|
|
|
|
|
|
|
#### F2: OutputArguments
|
|
|
|
|
|
Output arguments are counterintuitive. Readers expect arguments to be inputs, not out- puts. If your function must change the state of something, have it change the state of the object it is called on. (See "Output Arguments" on page 45.)
|
|
|
Output arguments are counterintuitive. Readers expect arguments to be inputs, not out- puts. If your function must change the state of something, have it change the state of the object it is called on. (See "Output Arguments" on page 45. Text reproduced below.)
|
|
|
|
|
|
#### F3: Flag Arguments
|
|
|
|
|
|
Boolean arguments loudly declare that the function does more than one thing. They are
|
|
|
confusing and should be eliminated. (See "Flag Arguments" on page 41.)
|
|
|
confusing and should be eliminated. (See "Flag Arguments" on page 41. Text reproduced below.)
|
|
|
|
|
|
#### F4: Dead Function
|
|
|
|
... | ... | |