Module: Argos
- Defined in:
- lib/redshift/util/argos.rb
Overview
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.(argv, optdef)
p opts # ==> {"v"=>true, "n"=>10}
p argv # ==> ["filename"]
Features:
-
Operates on ARGV or any given array of strings.
-
Output is a hash of => value, ….
-
You can merge this hash on top of a hash of defaults if you want.
-
Supports both long (“–foo”) and short (“-f”) options.
-
A long option with an argument is –foo=bar or –foo bar.
-
A short option with an argument is -fbar or -f bar.
-
The options -x and –x are synonymous.
-
Short options with no args can be combined as -xyz in place of -x -y -z.
-
If -z takes an argument, then -xyz foo is same as -x -y -z foo.
-
The string “–” terminates option parsing, leaving the rest untouched.
-
The string “-” is not considered an option.
-
ARGV (or other given array) is modified: it has all parsed options and arguments removed, so you can use ARGF to treat the rest as input files.
-
Unrecognized arguments are left in the argument array. You can catch them with grep(/^-./), in case you want to pass them on to another program or warn the user.
-
Argument validation and conversion are in terms of an option definition hash, which specifies which options are allowed, the number of arguments for each (0 or 1), and how to generate the value from the argument, if any.
-
Repetition of args (“-v -v”, or “-vv”) can be handled by closures. See the example below.
-
Everything is ducky. For example, handlers only need an #arity method and a #[] method to be recognized as callable. Otherwise they are treated as static objects.
Limitations:
-
A particular option takes either 0 args or 1 arg. There are no optional arguments, in the sense of both “-x” and “-x3” being accepted.
-
Options lose their ordering in the output hash (but they are parsed in order and you can keep track using state in the handler closures).
-
There is no usage/help output.
Copyright © 2006-2009 Joel VanderWerf, [email protected].
License is the Ruby license. See www.ruby-lang.org.
Defined Under Namespace
Classes: OptionError
Class Method Summary collapse
-
.argument_missing(opt) ⇒ Object
Called when an option that takes an argument occurs at the end of the argv list, with no argument following it.
-
.handle(opt, handler, *args) ⇒ Object
:nodoc.
-
.parse_options(argv, optdef) ⇒ Object
Returns the hash of parsed options and argument values.
Class Method Details
.argument_missing(opt) ⇒ Object
Called when an option that takes an argument occurs at the end of the argv list, with no argument following it.
86 87 88 |
# File 'lib/redshift/util/argos.rb', line 86 def argument_missing opt raise OptionError, "#{opt}: no argument provided." end |
.handle(opt, handler, *args) ⇒ Object
:nodoc
90 91 92 93 94 |
# File 'lib/redshift/util/argos.rb', line 90 def handle opt, handler, *args # :nodoc args.empty? ? handler[] : handler[args[0]] rescue => ex raise OptionError, "#{opt}: #{ex}" end |
.parse_options(argv, optdef) ⇒ Object
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.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/redshift/util/argos.rb', line 125 def argv, optdef orig = argv.dup; argv.clear opts = {} loop do case (argstr=orig.shift) when nil, "--" argv.concat orig break when /^(--)([^=]+)=(.*)/, /^(-)([^-])(.+)/ short = ($1 == "-"); opt = $2; arg = $3 unless optdef.key?(opt) argv << argstr next end handler = optdef[opt] arity = (handler.arity rescue nil) opts[opt] = case arity when nil; orig.unshift("-#{arg}") if short; handler when 0,-1; orig.unshift("-#{arg}") if short; handle(opt, handler) else handle(opt, handler, arg) end when /^--(.+)/, /^-(.)$/ opt = $1 unless optdef.key?(opt) argv << argstr next end handler = optdef[opt] arity = (handler.arity rescue nil) opts[opt] = case arity when nil; handler when 0,-1; handle(opt, handler) else handle(opt, handler, orig.shift || argument_missing(opt)) end else argv << argstr end end opts end |