# Class: Cri::OptionParser

Inherits:
  Object
  - Object
  - Cri::OptionParser
  show all

Defined in:
  lib/cri/option_parser.rb

## Overview

Cri::OptionParser is used for parsing command-line 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, :multiple => true },
      { :short => 'p', :long => 'port', :argument => :required, :multiple => false },
    ]

For example, the following command-line 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

- #delegate ⇒ #option_added, #argument_added

  The delegate to which events will be sent.

- #options ⇒ Hash readonly

  The options that have already been parsed.

- #raw_arguments ⇒ Array readonly

  The arguments that have already been parsed, including the -- separator.

- #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 command-line arguments.

## Instance Method Summary collapse

- #arguments ⇒ Array

  Returns the arguments that have already been parsed.

- #initialize(arguments_and_options, definitions) ⇒ OptionParser constructor

  Creates a new parser with the given options/arguments and definitions.

- #run ⇒ Cri::OptionParser

  Parses the command-line 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.

Parameters:

- arguments_and_options (`Array<String>`) —

  An array containing the command-line arguments (will probably be `ARGS` for a root command)

- definitions (`Array<Hash>`) —

  An array of option definitions

    112
    113
    114
    115
    116
    117
    118
    119
    120
    121

    # File 'lib/cri/option_parser.rb', line 112

    def initialize(arguments_and_options, definitions)
      @unprocessed_arguments_and_options = arguments_and_options.dup
      @definitions = definitions

      @options       = {}
      @raw_arguments = []

      @running = false
      @no_more_options = false
    end

## Instance Attribute Details

### #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)`

Returns:

- (`#option_added`, `#argument_added`) —

  The delegate

    72
    73
    74

    # File 'lib/cri/option_parser.rb', line 72

    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.

Returns:

- (`Hash`) —

  The already parsed options.

    81
    82
    83

    # File 'lib/cri/option_parser.rb', line 81

    def options
      @options
    end

### #raw_arguments ⇒ `Array` (readonly)

Returns The arguments that have already been parsed, including the -- separator.

Returns:

- (`Array`) —

  The arguments that have already been parsed, including the -- separator.

    85
    86
    87

    # File 'lib/cri/option_parser.rb', line 85

    def raw_arguments
      @raw_arguments
    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.

Returns:

- (`Array`) —

  The not yet parsed options and arguments.

    91
    92
    93

    # File 'lib/cri/option_parser.rb', line 91

    def unprocessed_arguments_and_options
      @unprocessed_arguments_and_options
    end

## Class Method Details

### .parse(arguments_and_options, definitions) ⇒ `Cri::OptionParser`

Parses the command-line arguments. See the instance `parse` method for details.

Parameters:

- arguments_and_options (`Array<String>`) —

  An array containing the command-line arguments (will probably be `ARGS` for a root command)

- definitions (`Array<Hash>`) —

  An array of option definitions

Returns:

- (`Cri::OptionParser`) —

  The option parser self

    102
    103
    104

    # File 'lib/cri/option_parser.rb', line 102

    def self.parse(arguments_and_options, definitions)
      new(arguments_and_options, definitions).run
    end

## Instance Method Details

### #arguments ⇒ `Array`

Returns 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.

Returns:

- (`Array`) —

  The already parsed arguments.

    130
    131
    132

    # File 'lib/cri/option_parser.rb', line 130

    def arguments
      ArgumentArray.new(@raw_arguments).freeze
    end

### #run ⇒ `Cri::OptionParser`

Parses the command-line arguments into options and arguments.

During parsing, two errors can be raised:

Returns:

- (`Cri::OptionParser`) —

  The option parser self

Raises:

- IllegalOptionError if an unrecognised option was encountered, i.e. an option that is not present in the list of option definitions

- OptionRequiresAnArgumentError if an option was found that did not have a value, even though this value was required.

    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

    # File 'lib/cri/option_parser.rb', line 158

    def run
      @running = true

      while running?
        # Get next item
        e = @unprocessed_arguments_and_options.shift
        break if e.nil?

        if e == '--'
          handle_dashdash(e)
        elsif e =~ /^--./ && !@no_more_options
          handle_dashdash_option(e)
        elsif e =~ /^-./ && !@no_more_options
          handle_dash_option(e)
        else
          add_argument(e)
        end
      end

      add_defaults

      self
    ensure
      @running = false
    end

### #running? ⇒ `Boolean`

Returns true if the parser is running, false otherwise.

Returns:

- (`Boolean`) —

  true if the parser is running, false otherwise.

    135
    136
    137

    # File 'lib/cri/option_parser.rb', line 135

    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.

    143
    144
    145

    # File 'lib/cri/option_parser.rb', line 143

    def stop
      @running = false
    end