Skip to content

Instantly share code, notes, and snippets.

@mdunsmuir
Created October 17, 2012 22:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mdunsmuir/3908877 to your computer and use it in GitHub Desktop.
Save mdunsmuir/3908877 to your computer and use it in GitHub Desktop.
ruby alternative option parser
#
# simple option parser that supports negative numbers as arguments, because I needed to do that
#
# should mostly be a drop-in replacement for OptionParser's basic usage patterns
#
class MDOP
#
# class to hold each option's data (including its Proc)
#
class MDOption
attr_reader :short, :long, :desc, :block, :klass
def initialize(short, long, klass, desc, block)
@short = short
@long = long
if @short.nil? and @long.nil?
raise ArgumentError.nil("Short name and long name can't both be nil!")
elsif @short.nil?
@short = @long
elsif @long.nil?
@long = @short
end
@klass = klass
@desc = desc
@block = block
end
def parse(argv_r) # reversed argv
token = argv_r.pop
if token.match(@short) or token.match(@long)
if @klass # if this one has a value
val = argv_r.pop
if @klass == Integer # couldn't get a case statement to work here!
val = val.to_i
elsif @klass == Float
val = val.to_f
elsif @klass == String
else
raise ArgumentError.new("I can't read values of class #{@klass.to_s}!")
end
@block.call(val)
else # if it's just a flag
@block.call
end
return true
else
argv_r.push(token)
return false
end
end
end
attr_accessor :banner
def initialize(banner = nil)
@banner = banner
@opts = []
super
end
def to_s
return banner
end
def parse(argv)
argv_r = argv.reverse
extra_args = []
while(argv_r.size > 0)
found = false
@opts.each{ |opt|
if opt.parse(argv_r)
found = true
break
end
}
extra_args.push(argv_r.pop) unless found
end
return extra_args
end
def on(*args, &block)
raise "There's no point in defining an option without a block..." unless block
if args.size == 4
on_param(*args, block)
elsif args.size == 3
on_noparam(*args, block)
else
raise ArgumentError.new("you must supply four or five arguments!")
end
end
private
def on_noparam(short, long, desc, block)
@opts << MDOption.new(short, long, nil, desc, block)
end
def on_param(short, long, klass, desc, block)
@opts << MDOption.new(short, long, klass, desc, block)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment