Skip to content

Instantly share code, notes, and snippets.

@carlobaldassi
Created September 6, 2012 13:56
Show Gist options
  • Save carlobaldassi/3656509 to your computer and use it in GitHub Desktop.
Save carlobaldassi/3656509 to your computer and use it in GitHub Desktop.
ArgParse syntaxes

@add_arg_table (macro version)

Uses an internal parser to read settings in the cleanest possible way.

Example:

s = ArgParseSettings()
                                                        
@add_arg_table s begin                  # use a begin..end block to format nicely
    "--opt1"                            # each name introduces a new argument field
        nargs = '?'                     # each assignment is an option referred to the last name
        arg_type = Int                  # note: no commas, can use '='
        default => 0                    #       but '=>' and ':=' are still allowed
        constant = int(cos(0))          # expressions are allowed in option values
        help = "first option"
    "--karma", "-k"                     # the comma creates a tuple -> multiple names
        action = "count_invocations"
        help = "increase karma"
    "arg1"
        nargs = 2
        help = "first_argument, " *     # string concatenation works fine
               "two entries at once"
        required = true
    "arg2"
        nargs = '*'; required = false   # just like standard syntax, can use the semicolon
        default = {"no_arg_given"}
        help = "second argument, eats up " *
               "as many items as possible " *
               "before an option"
        ignored_with_a_warning    # not a string, not a tuple, not an assignment,
                                  # not a begin..end block: guess what will happen
     end
  • pros:
    • doesn't require using @options or even importing OptionsMod at all
    • can use assignments rather than =>
    • multiple names don't require vector syntax, just separate them with a comma (see -k option)
  • cons:
    • no expressions are allowed when specifying names (e.g. you cannot pass a name via a variable, or use concatenation etc.)
    • effectively introduces a sub-parser (quite simple and liberal, but still)
    • possibly susceptible to internal ast representation changes
    • potentially hard to understand error messages

The parser is liberal, alternative styles are possible:

@add_arg_table(s                 # can use function notation
  , "--opt1"
  , begin                        # begin..end blocks are just expanded, each statement
        nargs='?'                #     becoming a separate argument
        arg_type=Int
        default=0
        constant=1
        help="first option"
    end)

@add_arg_table(s                      # for people who really like commas
  , ["--karma", "-k"]
  ,     action=>"count_invocations"
  ,     help=>"increase karma"
  , "arg1"
  ,     nargs=>2
  ,     help=>"first_argument,"
            * "two entries at once"
  ,     required=>true
  , "arg2"
  ,     nargs=>'*'
  ,     default={"no_arg_given"}
  ,     help=>"second argument, eats up "
            * "as many items as possible "
            * "before an option"
  ,     required=>false
  )

add_arg_fields

Uses a closure to parse argument fields without needing to pass the settings variable all the time.

Example:

s = ArgParseSettings()

add_arg_fields(s) do a
    a("--opt1", @options(nargs=>'?',
                         arg_type=>Int,
                         default=>0,
                         constant=>1,
                         help=>"first option"))
    a(["--karma", "-k"], @options(action=>"count_invocations",
                                  help=>"increase karma"))
    a("arg1", @options(nargs=>2,
                       help=>"first_argument, " *
                             "two entries at once",
                              required=>true))
    a("arg2", @options(nargs=>'*',
                       default=>{"no_arg_given"},
                       help=>"second argument, eats up as many items " *
                             "as possible before an option",
                       required=>false))
end
  • pros:
    • no restrictions on the programming side
    • more familiar syntax (?)
  • cons:
    • more verbose and clumsy than @add_arg_table (requires @options, needs =>, lots of commas etc.)

add_arg_table (function version)

An extended version of the old add_argument, reads all data at once.

Example:

s = ArgParseSettings()

add_arg_table(s,
    "--opt1",          @options(nargs=>'?',
                                arg_type=>Int,
                                default=>0,
                                constant=>1,
                                help=>"first option"),
    ["--karma", "-k"], @options(action=>"count_invocations",
                                help=>"increase karma"),
    "arg1",            @options(nargs=>2,
                                help=>"first_argument," *
                                      "two entries at once",
                                required=>true),
    "arg2",            @options(nargs=>'*',
                                default=>{"no_arg_given"},
                                help=>"second argument, eats up " *
                                      "as many items as possible " *
                                      "before an option",
                                required=>false)
    )
  • pros:
    • less verbose than add_args_fields, has basically all the same pros
    • it's like an improved version of add_argument
  • cons:
    • still more verbose and clumsy than @add_arg_table
    • probably easier to make mistakes when passing huge argument lists (but can be still be split in parts if necessary)
    • error messages are not going to tell you which line was wrong (but hopefully the error message would have enough information to help spotting the problem)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment