variations on a theme (argument parsing)

You just need to think of the argument array as a stream of events and the parsing logic as the state machine that responds to the incoming events. The simplest possible thing you can do is perform a transition every time the incoming event (argument) begins with -. It is easier to demonstrate with code than to explain the whole thing.

Note that the above code will work even for argument sequences that look like -a 1 -b -a 2 and the results for -a will be the array [1, 2]. In that snippet we don’t do any destructive operations and leave ARGV as is. You could also perform the parsing destructively.

Destructive updates can be useful when you want to parse some arguments and then stop when you see a certain pattern like -- and then continue parsing with some other parser. This comes up when a single program can serve multiple purposes and decides what to do based on the value of a specific argument. Bundler and knife (chef utility) are good examples of such use cases.

So far we have been segmenting and accumulating the arguments in one pass through the argument array. That’s not the only way to do it. You can make several passes and accumulate the arguments as necessary.

Now instead of looking up the values for an argument in a hash we use a method to do it. In fact you can make the two interchangeable by using a lambda or a hash map initialized with a block. Here’s what the hash map version looks like and you get memoization for free.

The point is that this is all pretty lightweight. Next time you need to do argument parsing and don’t want to include an extra dependency then just copy and paste one of the above solutions. Even the hackiest of command line scripts deserves some kind of argument parsing.