4 ms·
It's the same command line flag design used by other programs at Google. The C++ library, which Rob had nothing to do with, is at https://code.google.com/p/gfla
by rsc 13y ago
It's the same command line flag design used by other programs at Google. The C++ library, which Rob had nothing to do with, is at https://code.google.com/p/gflags/ https://code.google.com/p/gflags/.
The major benefit is that different parts of the program can declare their flags separately, and they all get put together. When you're doing distributed flag definition like this, single-letter flags don't make much sense: you'd get collisions very quickly. Instead, a flag only has a long name, not long and short. At that point, there is no need to distinguish between - and --, so the parsers (both C++ and Go) do not.
You wrote that the parser insists on -key=value, but that's not true. Because all flags are "long names", all of these are equivalent:
-key value
-key=value
--key value
--key=value
If you prefer one over the others, use that one.
Rob and I came from the Plan 9 (really, early Unix) world of only single-letter flags, no long names at all. That may work for small programs, but it doesn't scale very well. The GNU "short and long" is a compromise to keep backwards compatibility with the short flag world, but it ends up creating two names for many things. There's no need for that compatibility if you're not trying to recreate Unix (like GNU is). Keep it simple: one name, don't bother caring whether people type - or --.
As others have pointed out, if you need GNU getopt compatibility or even Plan 9 compatibility, it is possible to implement as a separate library. I haven't looked recently, but I've been waiting for someone to implement such a library but using the actual flag registration from the standard flag package, so that moving from one flag syntax to the other is just a matter of calling a different parser in package main. All the actual flag creation need not change.
- jzwinck 13y agoThe gflags official documentation, presumably written at Google, has this to say about the different dash styles: > Despite this flexibility, we recommend using only a single form: --variable=value for non-boolean flags, and --variable/--novariable for boolean flags. This consistency will make your code more readable, and is also the format required for certain special-use cases like flagfiles. The one remaining inconsistency between this advice and GNU's is that the latter would spell it --no-variable.
- peterwwillis 13y agoOne could argue that -key value is much less simple than -X[=optional value]. Why would you ever need to "scale" a command to more than 30 options? At that point you have a command line string that's 200 characters long, which is completely impractical for a command line. And in terms of distributed flags, who says one command wouldn't end up with the same flag name as another command? Look at the gcc man page. It's ridiculous! They use a mix of longnames and short, and it's still confusing as hell. Why do they need this many options? Because for any given operation they want to be able to specify the overall options, language options, warning options, debugging options, optimization options, preprocessor options, assembler options, linker options, directory options, machine-dependent options, platform options, code gen options, etc. As if all of those options would relate to every single GCC operation! They seem to have a mandate that input from ARGV is the only way to determine how to run their program. And it works for them; using autoconf and Makefiles you can configure the options each command will use in a very fine-grained way. But the end result is that for 99% of these cases, you have to use autoconf and Makefiles to make sense of anything! So what the hell is the point of stuffing them all in ARGV if a human isn't even going to use them anyway? They could have just as easily set environment variables and been done with it (lord knows why; probably some 30-year-old backwards compatibility issue) I prefer the 'cvs' model of command-line processing. The creators knew they wanted one command which would let them do everything, but they also knew that there would be separate operations with their own options. So you specify a command, and then you specify your options. In this way, you know -a for 'ls' is probably going to be different than -a for 'diff' - but you can also look up these options incredibly easy using 'cvs --help command'. Now instead of having a soup of options to browse through, you know exactly what options relate to the specific operation you want to do. The program's execution and options become easier to understand using this option hierarchy. It also distributes well because your commands have unique names. And no more looking up the 1000-page manual to find the one option you wanted.
- jzwinck 13y agoDid you know about GCC's --help=CLASS syntax, like --help=warnings ? I didn't either, but your post motivated me to look it up. That's a bit like what you'd want--help only for specific types of things--but it has some bizarre aspects, such as no apparent CLASS defined by operation [-c|-S|-E], so there is still no obvious way to know from the docs that the only option relevant with -E is -D (I think!). Another fun quirk is --help=undocumented, to "Display only those options which are undocumented."
- sneak 13y ago> You wrote that the parser insists on -key=value, but that's not true. Because all flags are "long names", all of these are equivalent: > -key value -key=value --key value --key=value > If you prefer one over the others, use that one. Thank you, I had no idea! I support this design choice now.