Module: Gemma::Options

Defined in:
lib/gemma/options.rb

Overview

Helpers for processing command line arguments.

Defined Under Namespace

Classes: ExtractResult

Class Method Summary collapse

Class Method Details

.extract(names, options) ⇒ ExtractResult

Extract the last option with one of the given `names` from `input`.

Long form options of the form `–foo`, `–foo bar` and `–foo=bar` are supported (where `–foo` is the option name and `bar` is the argument in the last two forms).

Short form options of the form `-f`, `-fbar` and `-f bar` are supported (where `-f` is the option name and `bar` is the argument in the last two forms). However concatenated short forms are not supported; that is, the option `-fg` is interpreted as `-f g` (option `f` with argument `g`) rather than `-f -g` (options `f` and `g` with no arguments).

Abbreviated long form options (e.g. `–ex` for `–example`) are not supported, because this method doesn't know the full set of acceptable options, so it can't resolve ambiguities.

If an option appears more than once, the argument for the last one is returned, and the previous matching options and arguments are deleted (i.e. not returned in Gemma::Options::ExtractResult#remaining_options).

Matching options that appear after a `–` terminator are not extracted; they remain in the Gemma::Options::ExtractResult#remaining_options list.

The options parameter takes an array of arguments; to split a string into the appropriate form, you can use the Shellwords module in the ruby standard library.

Examples:

Gemma::Options.extract(%w(-a), %w(-a foo bar.txt))
#=> #<struct Gemma::Options::ExtractResult argument="foo",
#     remaining_options=["bar.txt"]>

Parameters:

  • names (Array<String>)

    one or more names for the option to extract (`['–file','-f']`, for example)

  • options (Array<String>)

    to extract from; you should ensure that there isn't leading/trailing whitespace (strip), because this method doesn't detect it

Returns:

  • (ExtractResult)

    contains the argument for the given option and the rest of the options


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/gemma/options.rb', line 56

def self.extract(names, options)
  options = options.dup
  result = nil
  done = []

  until options.empty?
    x = options.shift
    if x == '--'
      # Stop at the '--' terminator.
      done << x
      break
    elsif x =~ /^(--[^=]+)/
      if names.member?(Regexp.last_match(1))
        # Found a long style option; look for its argument (if any).
        result = \
          if x =~ /=(.*)$/
            Regexp.last_match(1)
          elsif !options.empty? && options.first !~ /^-./
            options.shift
          else
            ''
          end
      else
        done << x
      end
    elsif x =~ /^(-(.))(.*)/
      # Found a short style option; this may actually represent several
      # options; look for matching short options.
      name = Regexp.last_match(1)
      rest = Regexp.last_match(3)
      if names.member?(name)
        result = \
          if rest.length.positive?
            rest
          elsif !options.empty? && options.first !~ /^-./
            options.shift
          else
            ''
          end
      else
        done << x
      end
    else
      # Not an option; just let it pass through.
      done << x
    end
  end

  ExtractResult.new(result, done + options)
end