class Argvector

Argvector

Argvector provides a very simple means of parsing command line arguments.

Unlike other more complex libs this provides only the most basic and standard parsing functionality. In many cases that's all one really needs.

Usage is straight foward. Simply instantiate the class and query it for the particular “views” of the command line you want.

cargs = Argvector.new("-a foo -b=2")

cargs.parameters    #=> [['foo'],{'a'=>true,'b'=>'2'}]
cargs.flags         #=> ['a']
cargs.preoptions    #=> {'a'=>true}
cargs.preflags      #=> ['a']
cargs.subcommand    #=> ['foo', [], {'b'=>'2'}]

Attributes

argv[R]
arity[R]
line[R]

Public Class Methods

new(line=nil, arity=nil) click to toggle source

Takes the command line string (or array) and options. Options have flags and end with a hash of option arity.

# File lib/facets/argvector.rb, line 81
def initialize(line=nil, arity=nil)
  @line, @argv  = parse_line(line)
  @arity = parse_arity(arity||{})
  parse
end
parameters(*args) click to toggle source
# File lib/facets/argvector.rb, line 67
def self.parameters(*args)
  new.parameters(*args)
end

Public Instance Methods

arguments()

deprecate alias ?

Alias for: operands
assoc_options(args) click to toggle source

Parse flags takes the command line and transforms it such that flags (eg. -x and –x) are elemental associative arrays.

line = "--foo hello --try=this"
argv = Argvector.new(line)

args = line.split(/\s/)
argv.assoc_options(args)  #=> [ ["foo",true], "hello", ["try","this"] ]
# File lib/facets/argvector.rb, line 286
def assoc_options(args)
  ##args = args.dup
  args = multi_flag(args) #unless opts.include?(:simple)
  i = 0
  while i < args.size
    arg = args[i]
    case arg
    when /^-/
      arg = arg.sub(/^-{1,2}/,'')
      if arg.index('=')
        key, val = arg.split('=')
        args[i] = [key, val||true]
      elsif arity.key?(arg)
        cnt = arity[arg]
        key = arg
        val = args[i+1,cnt]
        args[i,cnt+1] = [[key, *val]]
        i += (cnt - 1)
      else
        key = arg
        args[i] = [key,true]
      end
    end
    i += 1
  end
  return args
end
flags() click to toggle source

Return flags, which are true options.

# File lib/facets/argvector.rb, line 109
def flags
  f = []
  @options.each do |k, v|
    if TrueClass===v or FalseClass===v  # not that it's ever false
      f << k
    end
  end
  return f
end
format_options(assoc_options) click to toggle source

Format flag options. This converts the associative array of options/flags into a hash. Repeat options will be placed in arrays.

# File lib/facets/argvector.rb, line 329
def format_options(assoc_options)
  opts = {}
  assoc_options.each do |k,v|
    if opts.key?(k)
      opts[k] = [opts[k]].flatten << v
    else
      opts[k] = v
    end
  end
  return opts
end
multi_flag(args=nil) click to toggle source

Split single letter option groupings into separate options. ie. -xyz => -x -y -z

# File lib/facets/argvector.rb, line 316
def multi_flag(args=nil)
  args ||= argv
  args.collect { |arg|
    if md = /^-(\w{2,})/.match( arg )
      md[1].split(//).collect { |c| "-#{c}" }
    else
      arg.dup
    end
  }.flatten
end
operands() click to toggle source

Returns operand array.

# File lib/facets/argvector.rb, line 90
def operands
  @operands
end
Also aliased as: arguments
options() click to toggle source

Returns options hash.

# File lib/facets/argvector.rb, line 98
def options
  @options
end
parameters() click to toggle source

Returns [operands, options], which is good for plugging directly into a method.

# File lib/facets/argvector.rb, line 104
def parameters
  return @operands, @options
end
parameters_without_duplicates() click to toggle source

Like parameters but without allowing for duplicate options.

# File lib/facets/argvector.rb, line 181
def parameters_without_duplicates
  opts = {}
  @options.each do |k,v|
    if Array===v
      opts[k] = v[0]
    else
      opts[k] =  v
    end
  end
  return @operands, opts
end
parse() click to toggle source

Basic parser partitions the command line into options and operands. Options are converted to a hash and the two parts are returned.

line = "--trace stamp --file=VERSION"
argv = Argvector.new(line)

args, keys = *argv.parse

args #=> ["stamp"]
keys #=> {"trace"=>true, "file"=>"VERSION"}
# File lib/facets/argvector.rb, line 207
def parse
  args = assoc_options(argv) #, *opts_arity)

  opts, opds = args.partition{ |a| Array === a }

  @operands = opds
  @options  = format_options(opts)

  return @operands, @options
end
parse_arity(arity) click to toggle source

Ensure arity is uniform.

# File lib/facets/argvector.rb, line 245
def parse_arity(arity)
  arity2 = {}
  arity.each{ |k,v| arity2[k.to_s] = v.to_i }
  return arity2
end
parse_line(line=nil) click to toggle source

First pass parser to split the command line into an array using Shellwords, if not already so divided.

# File lib/facets/argvector.rb, line 220
def parse_line(line=nil)
  if line
    case line
    when String
      argv = Shellwords.shellwords(line)
    else
      argv = line.to_ary.dup
      line = argv.join(' ')
    end
  else
    argv = ARGV.dup
    line = argv.join(' ')
  end
  return line, argv
end
parse_preoptions(args) click to toggle source

Parse preoptions. A “preoption” is one that occurs before the first operans (if any).

# File lib/facets/argvector.rb, line 253
def parse_preoptions(args)
  ##args = args.dup
  args = multi_flag(args) #unless opts.include?(:simple)

  flags = []
  while args.first =~ /^-/
    key = args.shift
    key.sub!(/^-{1,2}/,'')
    if key.index('=')
      key, val = key.split('=')
    elsif a = arity[key]
      val = args.slice!(0,a)
      val = val.first if a == 1
    else
      val = true
    end
    flags << [key, val]
  end

  flags = format_options(flags)

  return flags, args
end
preflags() click to toggle source

Same as flags but only returns flags in the preoptions.

# File lib/facets/argvector.rb, line 169
def preflags
  preopts, remainder = *parse_preoptions(argv)
  f = []
  preopts.each do |k, v|
    if TrueClass===v or FalseClass===v  # not that it's ever false
      f << k
    end
  end
  return f
end
preoptions() click to toggle source

Returns a hash of options that occur before the first operand. This works well with subcommand to get the main command's options.

line = "--trace stamp --file VERSION"
cargs = Argvector.new(line)
opts = cargs.preoptions
opts #=> {"trace"=>true}
# File lib/facets/argvector.rb, line 162
def preoptions
  preopts, remainder = *parse_preoptions(argv)
  return preopts
end
subcommand()
subcommand_with_arguments() click to toggle source

Assumes the first operand is a “subcommand” and returns it and the argments following it as another Arguments object.

TODO: This probably should be called 'subcommand'.

# File lib/facets/argvector.rb, line 146
def subcommand_with_arguments
  opts, args = *parse_preoptions(argv)
  cmd = args.shift
  subargs = self.class.new(args, @arity)
  return cmd, subargs
end
subcommand_with_parameters() click to toggle source

Assumes the first operand is a “subcommand” and returns it and the argments following it as parameters.

# File lib/facets/argvector.rb, line 122
def subcommand_with_parameters
  opts, args = *parse_preoptions(argv)
  cmd = args.shift
  subargs = self.class.new(args, @arity)
  return [cmd, *subargs.parameters]
end
Also aliased as: subcommand
subcommand_with_preoptions() click to toggle source
# File lib/facets/argvector.rb, line 132
def subcommand_with_preoptions
  pre, args = *parse_preoptions(argv)
  cmd = args.shift
  subargs = self.class.new(args, @arity)
  args, opts = *subargs.parameters
  return [cmd, args, pre.merge(opts)]
end