Method: OptionParser#make_switch

Defined in:
lib/optparse.rb

#make_switch(opts, block = nil) ⇒ Object

Creates an OptionParser::Switch from the parameters. The parsed argument value is passed to the given block, where it can be processed.

See at the beginning of OptionParser for some full examples.

opts can include the following elements:

Argument style:

One of the following:

:NONE, :REQUIRED, :OPTIONAL
Argument pattern:

Acceptable option argument format, must be pre-defined with OptionParser.accept or OptionParser#accept, or Regexp. This can appear once or assigned as String if not present, otherwise causes an ArgumentError. Examples:

Float, Time, Array
Possible argument values:

Hash or Array.

[:text, :binary, :auto]
%w[iso-2022-jp shift_jis euc-jp utf8 binary]
{ "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
Long style switch:

Specifies a long style switch which takes a mandatory, optional or no argument. It’s a string of the following form:

"--switch=MANDATORY" or "--switch MANDATORY"
"--switch[=OPTIONAL]"
"--switch"
Short style switch:

Specifies short style switch which takes a mandatory, optional or no argument. It’s a string of the following form:

"-xMANDATORY"
"-x[OPTIONAL]"
"-x"

There is also a special form which matches character range (not full set of regural expression):

"-[a-z]MANDATORY"
"-[a-z][OPTIONAL]" 
"-[a-z]"
Argument style and description:

Instead of specifying mandatory or optional orguments directly in the switch parameter, this separate parameter can be used.

"=MANDATORY"
"=[OPTIONAL]"
Description:

Description string for the option.

"Run verbosely"
Handler:

Handler for the parsed argument value. Either give a block or pass a Proc or Method as an argument.



1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
# File 'lib/optparse.rb', line 1059

def make_switch(opts, block = nil)
  short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
  ldesc, sdesc, desc, arg = [], [], []
  default_style = Switch::NoArgument
  default_pattern = nil
  klass = nil
  o = nil
  n, q, a = nil

  opts.each do |o|
    # argument class
    next if search(:atype, o) do |pat, c|
      klass = notwice(o, klass, 'type')
      if not_style and not_style != Switch::NoArgument
        not_pattern, not_conv = pat, c
      else
        default_pattern, conv = pat, c
      end
    end

    # directly specified pattern(any object possible to match)
    if !(String === o) and o.respond_to?(:match)
      pattern = notwice(o, pattern, 'pattern')
      conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
      next
    end

    # anything others
    case o
    when Proc, Method
      block = notwice(o, block, 'block')
    when Array, Hash
      case pattern
      when CompletingHash
      when nil
        pattern = CompletingHash.new
        conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
      else
        raise ArgumentError, "argument pattern given twice"
      end
      o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}}
    when Module
      raise ArgumentError, "unsupported argument type: #{o}"
    when *ArgumentStyle.keys
      style = notwice(ArgumentStyle[o], style, 'style')
    when /^--no-([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      not_pattern, not_conv = search(:atype, o) unless not_style
      not_style = (not_style || default_style).guess(arg = a) if a
      default_style = Switch::NoArgument
      default_pattern, conv = search(:atype, FalseClass) unless default_pattern
      ldesc << "--no-#{q}"
      long << 'no-' + (q = q.downcase)
      nolong << q
    when /^--\[no-\]([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      o = notwice(a ? Object : TrueClass, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--[no-]#{q}"
      long << (o = q.downcase)
      not_pattern, not_conv = search(:atype, FalseClass) unless not_style
      not_style = Switch::NoArgument
      nolong << 'no-' + o
    when /^--([^\[\]=\s]*)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      ldesc << "--#{q}"
      long << (o = q.downcase)
    when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
      q, a = $1, $2
      o = notwice(Object, klass, 'type')
      if a
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      sdesc << "-#{q}"
      short << Regexp.new(q)
    when /^-(.)(.+)?/
      q, a = $1, $2
      if a
        o = notwice(NilClass, klass, 'type')
        default_style = default_style.guess(arg = a)
        default_pattern, conv = search(:atype, o) unless default_pattern
      end
      sdesc << "-#{q}"
      short << q
    when /^=/
      style = notwice(default_style.guess(arg = o), style, 'style')
      default_pattern, conv = search(:atype, Object) unless default_pattern
    else
      desc.push(o)
    end
  end

  default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
  if !(short.empty? and long.empty?)
    s = (style || default_style).new(pattern || default_pattern,
                                     conv, sdesc, ldesc, arg, desc, block)
  elsif !block
    raise ArgumentError, "no switch given" if style or pattern
    s = desc
  else
    short << pattern
    s = (style || default_style).new(pattern,
                                     conv, nil, nil, arg, desc, block)
  end
  return s, short, long,
    (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
    nolong
end