Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

144 lines (117 sloc) 3.949 kb
class OptionParser {
"""
Parses command-line options from a given @Array@ (usually @ARGV) and
executes registered handlers for options specified.
"""
class Option {
read_slots: ('option, 'arg, 'doc_string, 'block)
def initialize: @option arg: @arg doc: @doc_string block: @block
def name_with_arg {
if: @arg then: {
"#{@option} [#{@arg}]"
} else: {
@option
}
}
}
class InvalidOptionsError : StandardError
read_slots: ('options, 'parsed_options)
read_write_slots: ('banner, 'exit_on_help, 'remove_after_parsed)
def initialize: @block (nil) {
"""
@block (Optional) @Block@ to be called with @self for easy setup.
Creates a new OptionParser.
Example:
o = OptionParser new: @{
with: \"--my-option\" doc: \"Sets some option value\" do: {
# do stuff in here...
}
}
o parse: ARGV # parse options from ARGV
"""
@options = <[]>
@parsed_options = <[]>
@banner = nil
@exit_on_help = true
@remove_after_parsed = false
with: "--help" doc: "Display this information" do: {
print_help_info
{ System exit } if: @exit_on_help
}
{ @block call: [self] } if: @block
}
def with: option_string doc: doc_string do: block ('identity) {
"""
@option_string Option flag and (optional) argument within \"[]\", e.g. \"--file [filename]\".
@doc_string Documentation @String@ for @option_string that is used in the standard @--help option.
@block @Block@ called if @option_string is matched during parsing. If the option takes an argument it will be passed to @block as an argument.
Example:
o = OptionParser new
o with: \"--file [filename]\" doc: \"Use this file for processing\" do: |filename| {
# do something with filename
}
"""
option, arg = option_string split: " "
if: arg then: {
match arg {
case /\[(.+)\]/ -> |_, arg_name|
arg = arg_name downcase
case _ ->
error_reason = "Could not correctly parse option argument: #{arg}"
InvalidOptionsError raise: error_reason
}
}
o = Option new: option arg: arg doc: doc_string block: block
@options[option]: o
}
def parse: args {
"""
@args @Array@ of arguments to parse options from. Typically you'd pass @ARGV here.
Parses options from @args and executes registered option handlers.
"""
@options each: |name opt| {
if: (args index: name) then: |idx| {
block = opt block
match block arity {
case 0 -> block call
case 1 ->
arg = args at: (idx + 1)
block call: [arg]
@parsed_options[name]: arg
{ args remove_at: idx } if: @remove_after_parsed
}
{ args remove_at: idx } if: @remove_after_parsed
}
}
}
def parse_hash: args {
"""
@args @Array@ of arguments to parse options from. Typically you'd pass @ARGV here.
Parses options as @Hash@ from @args and executes registered option handlers.
Example:
o = OptionParser new: @{
with: \"--some-option [option_value]\" doc: \"some docstring\"
# ...
}
opts = o parse_hash: [\"--some-option\", \"some-value\"]
opts # => <[\"--some-option\" => \"some-value\"]>
"""
parse: args
parsed_options
}
def print_help_info {
"""
Displays the @--help information on @*stdout* based on all options that
were registered via @OptionParser#with:doc:do:@.
"""
max_size = @options map: |name opt| { opt name_with_arg size } . max
if: @banner then: {
*stdout* println: @banner
*stdout* println
}
@options keys sort each: |name| {
opt = @options[name]
*stdout* printf(" %-#{max_size}s %s\n", opt name_with_arg, opt doc_string)
}
}
}
Jump to Line
Something went wrong with that request. Please try again.