The Way You Parse Command Line Options Is Wrong

     Sorry to break it to you, but the word is out. The way you parse command line options is wrong. Backwards, even. Quaint, some might say.

     Let's look at the grim reality of the situation:

  • Writing command-line option parsing code suuuuuuuucks. No one likes it.

  • Ideally, you have a really nice usage message. No one appreciates it.

  • Every single environment does it slightly differently. No one reuses code.

     Has anyone ever offered you a reward for the best command line option parsing? No? Well, that hasn't happened to me either. Or anyone I know, in fact. There's a reason for this, and it's that no one cares about that part of the code (unless it sucks).

What if, in the style of literate programming, you wrote self-documenting command line options?

     That's pretty much the idea behind docopt. It's similar to "Literate Testing", the idea that documentation contains embedded tests meant for the user to read. Docopt could be called "Literate Usage Strings".

     You write the final usage string in a format docopts can understand, and then tell a library to figure out the rest. Actually, anyone familiar with typical unix options code will already know 90% of the conventions. Docopts started its life as a Python project, but has since graduated to cross-platform status as other language implementations have emerged. (C, C++, Java)

I'm a busy programmer; I love any library that helps me lighten my cognitive load.

Python example:
  myprog [ -o <DIR> | --outputdir=<DIR> ] INPUT                                 
  myprog [ -h | --help | -v | --version ]                                       

  INPUT                  input file [default: <stdin>]                          
  -o --outputdir <DIR>   specify output file [default: outputdir]               
  -h --help              show this screen                                       
  -v --version           show version                                           

from docopt import docopt  
if __name__ == '__main__':  
  options = docopt(__doc__, version=__version__)

     So, in addition to the size of the actual usage string, we've coded up the command line parsing in just one line. Two, if you count the import. Factor in the cross-platform functionality, and this library becomes a great solution for an age-old problem. It's a welcome addition to my toolchest.