class OptimistXL::Option

Attributes

default[RW]
long[RW]
max_args[R]
min_args[R]
multi_given[W]
name[RW]
permitted[RW]
permitted_response[RW]
short[R]

Public Class Methods

create(name, _desc="", opts={}, _settings={}) click to toggle source

Determines which type of object to create based on arguments passed to OptimistXL::opt. This is trickier in OptimistXL, than other cmdline parsers (e.g. Slop) because we allow the default: to be able to set the option's type.

# File lib/optimist_xl.rb, line 1034
def self.create(name, _desc="", opts={}, _settings={})

  opttype = OptimistXL::Parser.registry_getopttype(opts[:type])
  opttype_from_default = get_klass_from_default(opts, opttype)
  #DEBUG# puts "\nopt:#{opttype||'nil'} ofd:#{opttype_from_default}"  if opttype_from_default
  if opttype && opttype_from_default && !opttype.compatible_with?(opttype_from_default) # opttype.is_a? opttype_from_default.class
    raise ArgumentError, ":type specification (#{opttype.class}) and default type don't match (default type is #{opttype_from_default.class})" 
  end
  
  opt_inst = (opttype || opttype_from_default || OptimistXL::BooleanOption.new)

  ## fill in :long
  opt_inst.long.set(name, opts[:long], opts[:alt])

  ## fill in :short
  opt_inst.short.add opts[:short]

  ## fill in :multi
  multi_given = opts[:multi] || false
  opt_inst.multi_given = multi_given

  ## fill in :default for flags
  defvalue = opts[:default] || opt_inst.default

  ## fill in permitted values
  permitted = opts[:permitted] || nil

  ## autobox :default for :multi (multi-occurrence) arguments
  defvalue = [defvalue] if defvalue && multi_given && !defvalue.kind_of?(Array)
  opt_inst.permitted = permitted
  opt_inst.permitted_response = opts[:permitted_response] if opts[:permitted_response]
  opt_inst.default = defvalue
  opt_inst.name = name
  opt_inst.opts = opts
  opt_inst
end
handle_long_opt(lopt, name) click to toggle source
# File lib/optimist_xl.rb, line 1105
def self.handle_long_opt(lopt, name)
  lopt = lopt ? lopt.to_s : name.to_s.gsub("_", "-")
  lopt = case lopt
         when /^--([^-].*)$/ then $1
         when /^[^-]/        then lopt
         else                     raise ArgumentError, "invalid long option name #{lopt.inspect}"
         end
end
handle_short_opt(sopt) click to toggle source
# File lib/optimist_xl.rb, line 1114
def self.handle_short_opt(sopt)
  sopt = sopt.to_s if sopt && sopt != :none
  sopt = case sopt
         when /^-(.)$/          then $1
         when nil, :none, /^.$/ then sopt
         else                   raise ArgumentError, "invalid short option name '#{sopt.inspect}'"
         end

  if sopt
    raise ArgumentError, "a short option name can't be a number or a dash" if sopt =~ ::OptimistXL::Parser::INVALID_SHORT_ARG_REGEX
  end
  return sopt
end
new() click to toggle source
# File lib/optimist_xl.rb, line 866
def initialize
  @long = LongNames.new
  @short = ShortNames.new # can be an Array of one-char strings, a one-char String, nil or :none
  @name = nil
  @multi_given = false
  @hidden = false
  @default = nil
  @permitted = nil
  @permitted_response = "option '%{arg}' only accepts %{valid_string}"
  @optshash = Hash.new()
  @min_args = 1
  @max_args = 1
  # maximum max_args is likely ~~ 128*1024, as linux MAX_ARG_STRLEN is 128kiB
end
register_alias(*alias_keys) click to toggle source

Provide a way to register symbol aliases to the Parser

# File lib/optimist_xl.rb, line 1021
def self.register_alias(*alias_keys)
  alias_keys.each do |alias_key|
    # pass in the alias-key and the class
    Parser.register(alias_key, self)
  end
end

Private Class Methods

get_klass_from_default(opts, opttype) click to toggle source
# File lib/optimist_xl.rb, line 1085
def self.get_klass_from_default(opts, opttype)
  ## for options with :multi => true, an array default doesn't imply
  ## a multi-valued argument. for that you have to specify a :type
  ## as well. (this is how we disambiguate an ambiguous situation;
  ## see the docs for Parser#opt for details.)

  disambiguated_default = if opts[:multi] && opts[:default].is_a?(Array) && opttype.nil?
                            opts[:default].first
                          else
                            opts[:default]
                          end

  return nil if disambiguated_default.nil?
  type_from_default = get_type_from_disdef(opts[:default], opttype, disambiguated_default)
  return OptimistXL::Parser.registry_getopttype(type_from_default)
end
get_type_from_disdef(optdef, opttype, disambiguated_default) click to toggle source
# File lib/optimist_xl.rb, line 1072
def self.get_type_from_disdef(optdef, opttype, disambiguated_default)
  if disambiguated_default.is_a? Array
    return(optdef.first.class.name.downcase + "s") if !optdef.empty?
    if opttype
      raise ArgumentError, "multiple argument type must be plural" unless opttype.max_args > 1
      return nil
    else
      raise ArgumentError, "multiple argument type cannot be deduced from an empty array"
    end
  end
  return disambiguated_default.class.name.downcase
end

Public Instance Methods

array_default?() click to toggle source

|@min_args | @max_args | ----------———–+ | 0 | 0 | formerly flag?==true (option without any arguments) | 1 | 1 | formerly single_arg?==true (single-parameter/normal option) | 1 | >1 | formerly multi_arg?==true | ? | ? | presumably illegal condition. untested.

# File lib/optimist_xl.rb, line 909
def array_default? ; self.default.kind_of?(Array) ; end
callback() click to toggle source
# File lib/optimist_xl.rb, line 913
def callback ; opts(:callback) ; end
compatible_with?(other_option) click to toggle source

Check that an option is compatible with another option. By default, checking that they are the same class, but we can override this in the subclass as needed.

# File lib/optimist_xl.rb, line 885
def compatible_with?(other_option)
  self.is_a? other_option.class
end
desc() click to toggle source
# File lib/optimist_xl.rb, line 915
def desc ; opts(:desc) ; end
description_with_default(str) click to toggle source

Format the educate-line description including the default-value(s)

# File lib/optimist_xl.rb, line 952
def description_with_default(str)
  return str unless default
  default_s = case default
              when Array
                default.join(', ')
              else
                format_stdio(default).to_s
              end
  return "#{str} (Default: #{default_s})"
end
description_with_permitted(str) click to toggle source

Format the educate-line description including the permitted-value(s)

# File lib/optimist_xl.rb, line 964
def description_with_permitted(str)
  permitted_s = case permitted
                when Array
                  permitted.map do |p|
                    format_stdio(p).to_s
                  end.join(', ')
                when Range
                  permitted.to_a.map(&:to_s).join(', ')
                when Regexp
                  permitted.to_s
                end
  return "#{str} (Permitted: #{permitted_s})"
end
doesnt_need_autogen_short() click to toggle source
# File lib/optimist_xl.rb, line 911
def doesnt_need_autogen_short ; !short.auto || !short.chars.empty? ; end
educate() click to toggle source
# File lib/optimist_xl.rb, line 926
def educate
  optionlist = []
  optionlist.concat(short.chars.map { |o| "-#{o}" })
  optionlist.concat(long.names.map { |o| "--#{o}" })
  optionlist.compact.join(', ') + type_format + (min_args==0 && default ? ", --no-#{long}" : "")
end
format_stdio(obj) click to toggle source

Format stdio like objects to a string

# File lib/optimist_xl.rb, line 942
def format_stdio(obj)
  case obj
  when $stdout   then '<stdout>'
  when $stdin    then '<stdin>'
  when $stderr   then '<stderr>'
  else obj # pass-through-case
  end
end
full_description() click to toggle source

Format the educate-line description including the default and permitted value(s)

# File lib/optimist_xl.rb, line 934
def full_description
  desc_str = desc
  desc_str = description_with_default desc_str if default
  desc_str = description_with_permitted desc_str if permitted
  desc_str
end
multi() click to toggle source
# File lib/optimist_xl.rb, line 898
def multi ; @multi_given ; end
Also aliased as: multi?
multi?()
Alias for: multi
opts(key) click to toggle source
# File lib/optimist_xl.rb, line 889
def opts(key)
  @optshash[key]
end
opts=(o) click to toggle source
# File lib/optimist_xl.rb, line 893
def opts=(o)
  @optshash = o
end
parse(_paramlist, _neg_given) click to toggle source
# File lib/optimist_xl.rb, line 919
def parse(_paramlist, _neg_given)
  raise NotImplementedError, "parse must be overridden for newly registered type"
end
permitted_type_valid?() click to toggle source
# File lib/optimist_xl.rb, line 990
def permitted_type_valid?
  return true if permitted.nil?
  return true if permitted.is_a? Array
  return true if permitted.is_a? Range
  return true if permitted.is_a? Regexp
  false
end
permitted_valid_string() click to toggle source
# File lib/optimist_xl.rb, line 978
def permitted_valid_string
  case permitted
  when Array
    return "one of: " + permitted.to_a.map(&:to_s).join(', ')
  when Range
    return "value in range of: #{permitted}"
  when Regexp
    return "value matching: #{permitted.inspect}"
  end
  raise StandardError, "invalid branch"
end
permitted_value?(val) click to toggle source

incoming values from the command-line should be strings, so we should stringify any permitted types as the basis of comparison.

# File lib/optimist_xl.rb, line 1009
def permitted_value?(val)
  case permitted
  when nil then true
  when Regexp then val.match permitted
  when Range then permitted.to_a.map(&:to_s).include? val
  when Array then permitted.map(&:to_s).include? val
  else false
  end
end
required?() click to toggle source
# File lib/optimist_xl.rb, line 917
def required? ; opts(:required) ; end
type_format() click to toggle source

provide type-format string. default to empty, but user should probably override it

# File lib/optimist_xl.rb, line 924
def type_format ; "" ; end
validate_permitted(arg, value) click to toggle source
# File lib/optimist_xl.rb, line 998
def validate_permitted(arg, value)
  return true if permitted.nil?
  unless permitted_value?(value)
    format_hash = {arg: arg, given: value, value: value, valid_string: permitted_valid_string(), permitted: permitted }
    raise CommandlineError, permitted_response % format_hash
  end
  true
end