Ten Essential Development Practices
by Damian Conway
|
Pages: 1, 2, 3, 4, 5, 6, 7, 8
A large part of making interfaces consistent is being consistent in specifying the individual components of those interfaces. Some conventions that may help to design consistent and predictable interfaces include:
Require a flag preceding every piece of command-line data, except filenames.
Users don't want to have to remember that your application requires "input file, output file, block size, operation, fallback strategy," and requires them in that precise order:
> lustrate sample_data proc_data 1000 normalize logThey want to be able to say explicitly what they mean, in any order that suits them:
> lustrate sample_data proc_data -op=normalize -b1000 --fallback=logProvide a flag for each filename, too, especially when a program can be given files for different purposes.
Users might also not want to remember the order of the two positional filenames, so let them label those arguments as well, and specify them in whatever order they prefer:
> lustrate -i sample_data -op normalize -b1000 --fallback log -o proc_dataUse a single
-prefix for short-form flags, up to three letters (-v,-i,-rw,-in,-out).Experienced users appreciate short-form flags as a way of reducing typing and limiting command-line clutter. Don't make them type two dashes in these shortcuts.
Use a double
--prefix for longer flags (--verbose,--interactive,--readwrite,--input,--output).Flags that are complete words improve the readability of a command line (in a shell script, for example). The double dash also helps to distinguish between the longer flag name and any nearby file names.
If a flag expects an associated value, allow an optional
=between the flag and the value.Some people prefer to visually associate a value with its preceding flag:
> lustrate -i=sample_data -op=normalize -b=1000 --fallback=log -o=proc_dataOthers don't:
> lustrate -i sample_data -op normalize -b1000 --fallback log -o proc_dataStill others want a bit each way:
> lustrate -i sample_data -o proc_data -op=normalize -b=1000 --fallback=logLet the user choose.
Allow single-letter options to be "bundled" after a single dash.
It's irritating to have to type repeated dashes for a series of flags:
> lustrate -i sample_data -v -l -xAllow experienced users to also write:
> lustrate -i sample_data -vlxProvide a multi-letter version of every single-letter flag.
Short-form flags may be nice for experienced users, but they can be troublesome for new users: hard to remember and even harder to recognize. Don't force people to do either. Give them a verbose alternative to every concise flag; full words that are easier to remember, and also more self-documenting in shell scripts.
Always allow
-as a special filename.A widely used convention is that a dash (
-) where an input file is expected means "read from standard input," and a dash where an output file is expected means "write to standard output."Always allow
--as a file list marker.Another widely used convention is that the appearance of a double dash (
--) on the command line marks the end of any flagged options, and indicates that the remaining arguments are a list of filenames, even if some of them look like flags.
6. Agree Upon a Coherent Layout Style and Automate It with perltidy
Formatting. Indentation. Style. Code layout. Whatever you choose to call it, it's one of the most contentious aspects of programming discipline. More and bloodier wars have been fought over code layout than over just about any other aspect of coding.
What is the best practice here? Should you use classic Kernighan and Ritchie style? Or go with BSD code formatting? Or adopt the layout scheme specified by the GNU project? Or conform to the Slashcode coding guidelines?
Of course not! Everyone knows that <insert your personal coding style here> is the One True Layout Style, the only sane choice, as ordained by <insert your favorite Programming Deity here> since Time Immemorial! Any other choice is manifestly absurd, willfully heretical, and self-evidently a Work of Darkness!
That's precisely the problem. When deciding on a layout style, it's hard to decide where rational choices end and rationalized habits begin.
Adopting a coherently designed approach to code layout, and then applying that approach consistently across all your coding, is fundamental to best-practice programming. Good layout can improve the readability of a program, help detect errors within it, and make the structure of your code much easier to comprehend. Layout matters.
However, most coding styles--including the four mentioned earlier--confer those benefits almost equally well. While it's true that having a consistent code layout scheme matters very much indeed, the particular code layout scheme you ultimately decide upon does not matter at all! All that matters is that you adopt a single, coherent style; one that works for your entire programming team, and, having agreed upon that style, that you then apply it consistently across all your development.

