module Argos

A slim command-line parser that does one thing well: turn an array of strings, such as ARGV, into a hash of recognized options and their arguments, leaving unrecognized strings in the original array.

Argos was Odysseus' faithful dog, who was good at recognizing ;)

Synopsis:

require 'argos'

optdef = {
  "v"   => true,
  "n"   => proc {|arg| Integer(arg)}
}

argv = %w{-v -n10 filename}
opts = Argos.parse_options(argv, optdef)
p opts    # ==> {"v"=>true, "n"=>10}
p argv    # ==> ["filename"]

Features:

Limitations:

Copyright (C) 2006-2009 Joel VanderWerf, vjoel@users.sourceforge.net.

License is the Ruby license. See www.ruby-lang.org.

Public Instance Methods

argument_missing(opt) click to toggle source

Called when an option that takes an argument occurs at the end of the argv list, with no argument following it.

   # File lib/tkar/argos.rb
86 def argument_missing opt
87   raise OptionError, "#{opt}: no argument provided."
88 end
handle(opt, handler, *args) click to toggle source
   # File lib/tkar/argos.rb
90 def handle opt, handler, *args # :nodoc
91   args.empty? ?  handler[] : handler[args[0]]
92 rescue => ex
93   raise OptionError, "#{opt}: #{ex}"
94 end
parse_options(argv, optdef) click to toggle source

Returns the hash of parsed options and argument values. The argv array is modified: every recognized option and argument is deleted.

The optdef hash defines the options and their arguments.

Each key is an option name (without “-” chars).

The value for a key in optdef is used to generate the value for the same key in the options hash returned by this method.

If the value has an arity method and arity > 0, the value is considered to be a handler; it is called with the argument string to return the value associated with the option in the hash returned by the method.

If the arity <= 0, the value is considered to be a handler for an option without arguments; it is called with no arguments to return the value of the option.

If there is no arity method, the object itself is used as the value of the option.

Only one kind of input will cause an exception (not counting exceptions raised by handler code or by bugs):

  • An option is found at the end of the list, and it requires an argument. This results in a call to argument_missing, which by default raises OptionError.

    # File lib/tkar/argos.rb
125 def parse_options argv, optdef
126   orig = argv.dup; argv.clear
127   opts = {}
128 
129   loop do
130     case (argstr=orig.shift)
131     when nil, "--"
132       argv.concat orig
133       break
134 
135     when /^(--)([^=]+)=(.*)/, /^(-)([^-])(.+)/
136       short = ($1 == "-"); opt = $2; arg = $3
137       unless optdef.key?(opt)
138         argv << argstr
139         next
140       end
141       handler = optdef[opt]
142       arity = (handler.arity rescue nil)
143       opts[opt] =
144         case arity
145         when nil;   orig.unshift("-#{arg}") if short; handler
146         when 0,-1;  orig.unshift("-#{arg}") if short; handle(opt, handler)
147         else        handle(opt, handler, arg)
148         end
149 
150     when /^--(.+)/, /^-(.)$/
151       opt = $1
152       unless optdef.key?(opt)
153         argv << argstr
154         next
155       end
156       handler = optdef[opt]
157       arity = (handler.arity rescue nil)
158       opts[opt] =
159         case arity
160         when nil;   handler
161         when 0,-1;  handle(opt, handler)
162         else        handle(opt, handler, orig.shift || argument_missing(opt))
163         end
164 
165     else
166       argv << argstr
167     end
168   end
169 
170   opts
171 end