class Thor::Options

def assert_value!(switch)

def assert_value!(switch)
  raise Error, "no value provided for argument '#{switch}'" if peek.nil?
end

def check_required!(hash)

def check_required!(hash)
  for name, type in @switches
    if type == :required and !hash[undasherize(name)]
      raise Error, "no value provided for required argument '#{name}'"
    end
  end
end

def current_is_option?

def current_is_option?
  case peek
  when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
    valid?($1)
  when SHORT_SQ_RE
    $1.split('').any? { |f| valid?("-#{f}") }
  end
end

def dasherize(str)

def dasherize(str)
  (str.length > 1 ? "--" : "-") + str
end

def formatted_usage

def formatted_usage
  return "" if @switches.empty?
  @switches.map do |opt, type|
    case type
    when :boolean
      "[#{opt}]"
    when :required
      opt + "=" + opt.gsub(/\-/, "").upcase
    else
      sample = @defaults[undasherize(opt)]
      sample ||= case type
        when :optional then opt.gsub(/\-/, "").upcase
        when :numeric  then "N"
        end
      "[" + opt + "=" + sample.to_s + "]"
    end
  end.join(" ")
end

def initialize(switches)


).parse(args)
["--level", "-l"] => :numeric
["--verbose", "-v"] => true,
"--debug" => true,
opts = Thor::Options.new(

Example:

first letter of the short switch. The default type is :boolean.
The long switch _must_ be provided. The short switch defaults to the

by the user.
for each key depends on the type of switch and/or the value provided
containing each switch name, minus the '-', as a key. The value
elements that indicate the name and type of switch. Returns a hash
Takes an array of switches. Each array consists of up to three
def initialize(switches)
  @defaults = {}
  @shorts = {}
  @switches = switches.inject({}) do |mem, (name, type)|
    if name.is_a?(Array)
      name, *shorts = name
    else
      name = name.to_s
      shorts = []
    end
    # we need both nice and dasherized form of switch name
    if name.index('-') == 0
      nice_name = undasherize name
    else
      nice_name = name
      name = dasherize name
    end
    # if there are no shortcuts specified, generate one using the first character
    shorts << "-" + nice_name[0,1] if shorts.empty? and nice_name.length > 1
    shorts.each { |short| @shorts[short] = name }
    
    # normalize type
    case type
    when TrueClass then type = :boolean
    when String
      @defaults[nice_name] = type
      type = :optional
    when Numeric
      @defaults[nice_name] = type
      type = :numeric
    end
    
    mem[name] = type
    mem
  end
  
  # remove shortcuts that happen to coincide with any of the main switches
  @shorts.keys.each do |short|
    @shorts.delete(short) if @switches.key?(short)
  end
end

def non_opts

def non_opts
  leading_non_opts + trailing_non_opts
end

def normalize_switch(switch)

def normalize_switch(switch)
  @shorts.key?(switch) ? @shorts[switch] : switch
end

def parse(args, skip_leading_non_opts = true)

def parse(args, skip_leading_non_opts = true)
  @args = args
  # start with Thor::Options::Hash pre-filled with defaults
  hash = Hash.new @defaults
  
  @leading_non_opts = []
  if skip_leading_non_opts
    @leading_non_opts << shift until current_is_option? || @args.empty?
  end
  while current_is_option?
    case shift
    when SHORT_SQ_RE
      unshift $1.split('').map { |f| "-#{f}" }
      next
    when EQ_RE, SHORT_NUM
      unshift $2
      switch = $1
    when LONG_RE, SHORT_RE
      switch = $1
    end
    
    switch    = normalize_switch(switch)
    nice_name = undasherize(switch)
    type      = switch_type(switch)
    
    case type
    when :required
      assert_value!(switch)
      raise Error, "cannot pass switch '#{peek}' as an argument" if valid?(peek)
      hash[nice_name] = shift
    when :optional
      hash[nice_name] = peek.nil? || valid?(peek) || shift
    when :boolean
      hash[nice_name] = true
    when :numeric
      assert_value!(switch)
      unless peek =~ NUMERIC and $& == peek
        raise Error, "expected numeric value for '#{switch}'; got #{peek.inspect}"
      end
      hash[nice_name] = $&.index('.') ? shift.to_f : shift.to_i
    end
  end
  
  @trailing_non_opts = @args
  check_required! hash
  hash.freeze
  hash
end

def peek

def peek
  @args.first
end

def shift

def shift
  @args.shift
end

def switch_type(switch)

def switch_type(switch)
  @switches[switch]
end

def undasherize(str)

def undasherize(str)
  str.sub(/^-{1,2}/, '')
end

def unshift(arg)

def unshift(arg)
  unless arg.kind_of?(Array)
    @args.unshift(arg)
  else
    @args = arg + @args
  end
end

def valid?(arg)

def valid?(arg)
  @switches.key?(arg) or @shorts.key?(arg)
end