[Ann] Options -0.0.1, a simple option parser in 44 lines

Here you go. This is an offshoot of rush, the Ruby shell project.
I thought it might be useful to others.

#rush on freenode or visit



= Options

== Synopsis
Options implements a simple option parser.

== Version

== Installation

== Introduction
Configure the parser to accept the options that you desire,
which can be done all at once or is several invocations
and then simply pass Strings or Arrays to it to have them
parsed. The parser matches the given options to the ones
defined in Options#configure, leaves non-option arguments
(such as the path in 'ls -la /etc') alone. Any unknown
arguments raise an ArgumentError. The results of the parse
are returned as a Hash, see below. The accepted forms for
options are:

Short opts: -h, -ht, -h ARG, -h=ARG, -ht ARG.
Long opts: --help, --help ARG, --help=ARG. (No joining.)

Quoted strings are valid arguments but for Strings only.
Arrays should have parsed those at an earlier point.

The returned Hash is indexed by the names of the found
options. These indices point to an Array of arguments
to that option if any, or just true if not. The Hash
also contains a special index, :args, containing all
of the non-option arguments.

== Usage

   # Need the
   require 'options'

   # Need an instance
   o = Options.new

   # Set up the rules
   o.configure({'h' => {:desc => 'Shows a help message'},
                'p' => {:desc => 'Path to use.', :args => :yes},
                'quote' => {:desc => 'Some quote.', :args => :yes}})

   # Some data
   data = '-h abrakadabra -p /etc/foo/bar --quote "So be it." foo.rb'

   # Parse the data
   result = o.parse data

   # Look over the result
   p result['h'] # => true
   p result['p'] # => ["/etc/foo/bar"]
   p result['quote'] # => "So be it."
   p result[:args] # => ["abrakadabra", "foo.rb"]

== Current issues / ToDo
- Generate a 'usage' message from the descriptions.
- Arguments to options are greedy. If there is a non-option
   (i.e. an argument) after an option that takes an argument,
   it will be consumed. This can be avoided by passing it an
   empty string.
- Differentiate optional and required arguments?
- Convenience syntax for Options#configure?
- Single-argument options not storing an Array?

== Licence
BSD-like, see doc/README



template<typename duck>
void quack(duck& d) { d.quack(); }