Unix getopt versus Google's getopt variant and why Unix getopt wins

November 16, 2013

The longer title of this entry is 'why Google's version of getopt is right for Google but wrong for (almost) everyone else'.

One reaction to my rant about Go's getopt problem is to ask what the big problem is. Looked at in the right light, the rules implemented by Go's flag package (which are apparently the Google more or less standard for parsing flags) actually have a certain amount to recommend them because they're less ambiguous, more consistent, and less likely to surprise you. For example, consider this classic error: start with a command that takes a -t flag switch and a -f flag with an argument. One day someone in a hurry accidently writes this as 'cmd -ft fred bob' (instead of '-tf'). If you're lucky this will fail immediately with an error; if you're unlucky this quietly succeeds but does something quite different than what you expected. Google flag parsing reduces the chances of this by forcing you to always separate flags (so you can't do this just by transposing two characters).

In an environment where you are mostly or entirely using commands that parse flags this way, you get a number of benefits like this. I assume that this describes Google, which I suspect is heavily into internal tooling. But most environments are not like this at all; instead, commands using Go's flag package (or equivalents) are going to be the minority and the vast majority of commands you use will instead be either standard Unix commands or programs that use the same general argument parsing (partly because it's the default in almost everyone's standard library). In such environments the benefits that might come from Google flag parsing are dwarfed by the fact that it is just plain different from almost everything else you use. You will spend more time cursing because 'cmd -tf fred bob' gives you 'no such flag -tf' errors than you will ever likely save in the one (theoretical) time you type 'cmd -ft fred bob'.

(In theory you could also sort of solve the problem by always separating flag arguments even for programs that don't need this. But this is unlikely in practice since such programs are probably the majority of what you run and anyways, other bits of Go flag handling aren't at all compatible with standard Unix practice.)

In other words: inside Google, the de facto standard is whatever Google's tools do because you're probably mostly using them. Outside Google, the de facto standard is what the majority of programs do and that is standard Unix getopt (and extended GNU getopt). Deviations from de facto Unix getopt behavior cause the same problems that deviations from other de facto standards cause.

Now I'll admit that this is stating the case a bit too strongly. There are plenty of Unix programs that already deviate to a greater or lesser degree from standard Unix getopt. As with all interface standards a large part of what matters is how often people are going to use the deviant commands; the more frequently, the more you can get away with odd command behavior.

(You can also get away with more odd behavior if it's basically impossible to use your program casually. If an occasional user is going to have to re-read your documentation every time, well, you can (re)explain your odd command line behavior there.)

Written on 16 November 2013.
« Professional knowledge, certification, and regulation
Sending and receiving file descriptors in Python »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Nov 16 00:30:31 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.