Class: Cri::OptionParser
- Inherits:
-
Object
- Object
- Cri::OptionParser
- Defined in:
- lib/cri/option_parser.rb
Overview
Cri::OptionParser is used for parsing commandline options.
Option definitions are hashes with the keys ‘:short`, `:long` and `:argument` (optionally `:description` but this is not used by the option parser, only by the help generator). `:short` is the short, one-character option, without the `-` prefix. `:long` is the long, multi-character option, without the `–` prefix. `:argument` can be :required (if an argument should be provided to the option), :optional (if an argument may be provided) or :forbidden (if an argument should not be provided).
A sample array of definition hashes could look like this:
[
{ :short => 'a', :long => 'all', :argument => :forbidden },
{ :short => 'p', :long => 'port', :argument => :required },
]
For example, the following commandline options (which should not be passed as a string, but as an array of strings):
foo -xyz -a hiss -s -m please --level 50 --father=ani -n luke squeak
with the following option definitions:
[
{ :short => 'x', :long => 'xxx', :argument => :forbidden },
{ :short => 'y', :long => 'yyy', :argument => :forbidden },
{ :short => 'z', :long => 'zzz', :argument => :forbidden },
{ :short => 'a', :long => 'all', :argument => :forbidden },
{ :short => 's', :long => 'stuff', :argument => :optional },
{ :short => 'm', :long => 'more', :argument => :optional },
{ :short => 'l', :long => 'level', :argument => :required },
{ :short => 'f', :long => 'father', :argument => :required },
{ :short => 'n', :long => 'name', :argument => :required }
]
will be translated into:
{
:arguments => [ 'foo', 'hiss', 'squeak' ],
:options => {
:xxx => true,
:yyy => true,
:zzz => true,
:all => true,
:stuff => true,
:more => 'please',
:level => '50',
:father => 'ani',
:name => 'luke'
}
}
Defined Under Namespace
Classes: IllegalOptionError, OptionRequiresAnArgumentError
Instance Attribute Summary collapse
-
#arguments ⇒ Array
readonly
The arguments that have already been parsed.
-
#delegate ⇒ #option_added, #argument_added
The delegate to which events will be sent.
-
#options ⇒ Hash
readonly
The options that have already been parsed.
-
#unprocessed_arguments_and_options ⇒ Array
readonly
The options and arguments that have not yet been processed.
Class Method Summary collapse
-
.parse(arguments_and_options, definitions) ⇒ Cri::OptionParser
Parses the commandline arguments.
Instance Method Summary collapse
-
#initialize(arguments_and_options, definitions) ⇒ OptionParser
constructor
Creates a new parser with the given options/arguments and definitions.
-
#run ⇒ Cri::OptionParser
Parses the commandline arguments into options and arguments.
-
#running? ⇒ Boolean
True if the parser is running, false otherwise.
-
#stop ⇒ void
Stops the parser.
Constructor Details
#initialize(arguments_and_options, definitions) ⇒ OptionParser
Creates a new parser with the given options/arguments and definitions.
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cri/option_parser.rb', line 121 def initialize(, definitions) @unprocessed_arguments_and_options = .dup @definitions = definitions @options = {} @arguments = [] @running = false @no_more_options = false end |
Instance Attribute Details
#arguments ⇒ Array (readonly)
The arguments that have already been parsed.
If the parser was stopped before it finished, this will not contain all options and ‘unprocessed_arguments_and_options` will contain what is left to be processed.
94 95 96 |
# File 'lib/cri/option_parser.rb', line 94 def arguments @arguments end |
#delegate ⇒ #option_added, #argument_added
The delegate to which events will be sent. The following methods will be send to the delegate:
-
‘option_added(key, value, cmd)`
-
‘argument_added(argument, cmd)`
76 77 78 |
# File 'lib/cri/option_parser.rb', line 76 def delegate @delegate end |
#options ⇒ Hash (readonly)
The options that have already been parsed.
If the parser was stopped before it finished, this will not contain all options and ‘unprocessed_arguments_and_options` will contain what is left to be processed.
85 86 87 |
# File 'lib/cri/option_parser.rb', line 85 def @options end |
#unprocessed_arguments_and_options ⇒ Array (readonly)
The options and arguments that have not yet been processed. If the parser wasn’t stopped (using #stop), this list will be empty.
100 101 102 |
# File 'lib/cri/option_parser.rb', line 100 def @unprocessed_arguments_and_options end |
Class Method Details
.parse(arguments_and_options, definitions) ⇒ Cri::OptionParser
Parses the commandline arguments. See the instance ‘parse` method for details.
111 112 113 |
# File 'lib/cri/option_parser.rb', line 111 def self.parse(, definitions) self.new(, definitions).run end |
Instance Method Details
#run ⇒ Cri::OptionParser
Parses the commandline arguments into options and arguments.
During parsing, two errors can be raised:
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/cri/option_parser.rb', line 156 def run @running = true while running? # Get next item e = @unprocessed_arguments_and_options.shift break if e.nil? # Handle end-of-options marker if e == '--' @no_more_options = true # Handle incomplete options elsif e =~ /^--./ and !@no_more_options # Get option key, and option value if included if e =~ /^--([^=]+)=(.+)$/ option_key = $1 option_value = $2 else option_key = e[2..-1] option_value = nil end # Find definition definition = @definitions.find { |d| d[:long] == option_key } raise IllegalOptionError.new(option_key) if definition.nil? if [ :required, :optional ].include?(definition[:argument]) # Get option value if necessary if option_value.nil? option_value = @unprocessed_arguments_and_options.shift if option_value.nil? || option_value =~ /^-/ if definition[:argument] == :required raise OptionRequiresAnArgumentError.new(option_key) else @unprocessed_arguments_and_options.unshift(option_value) option_value = true end end end # Store option add_option(definition[:long].to_sym, option_value) else # Store option add_option(definition[:long].to_sym, true) end # Handle -xyz options elsif e =~ /^-./ and !@no_more_options # Get option keys option_keys = e[1..-1].scan(/./) # For each key option_keys.each do |option_key| # Find definition definition = @definitions.find { |d| d[:short] == option_key } raise IllegalOptionError.new(option_key) if definition.nil? if option_keys.length > 1 and definition[:argument] == :required # This is a combined option and it requires an argument, so complain raise OptionRequiresAnArgumentError.new(option_key) elsif [ :required, :optional ].include?(definition[:argument]) # Get option value option_value = @unprocessed_arguments_and_options.shift if option_value.nil? || option_value =~ /^-/ if definition[:argument] == :required raise OptionRequiresAnArgumentError.new(option_key) else @unprocessed_arguments_and_options.unshift(option_value) option_value = true end end # Store option add_option(definition[:long].to_sym, option_value) else # Store option add_option(definition[:long].to_sym, true) end end # Handle normal arguments else add_argument(e) end end self ensure @running = false end |
#running? ⇒ Boolean
Returns true if the parser is running, false otherwise.
133 134 135 |
# File 'lib/cri/option_parser.rb', line 133 def running? @running end |
#stop ⇒ void
This method returns an undefined value.
Stops the parser. The parser will finish its current parse cycle but will not start parsing new options and/or arguments.
141 142 143 |
# File 'lib/cri/option_parser.rb', line 141 def stop @running = false end |