Isn't it awesome how optparse and other option parsers generate help and
usage-messages based on your code?!
Hell no! You know what's awesome? It's when the option parser is generated based on the help and usage-message that you write in a docstring! This way you don't need to write this stupid repeatable parser-code, and instead can write a beautiful usage-message (the way you want it!), which adds readability to your code.
Now you can write an awesome, readable, clean, DRY code like that:
doc = "Usage: example.rb [options] <arguments>...
Options:
-h --help show this help message and exit
--version show version and exit
-v --verbose print status messages
-q --quiet report only file names
-r --repeat show all occurrences of the same error
--exclude=patterns exclude files or directories which match these comma
separated patterns [default: .svn,CVS,.bzr,.hg,.git]
--filename=patterns when parsing directories, only check filenames matching
these comma separated patterns [default: *.rb]
--select=errors select errors and warnings (e.g. E,W6)
--ignore=errors skip errors and warnings (e.g. E4,W)
--show-source show source code for each error
--statistics count errors and warnings
--count print total number of errors and warnings to standard
error and set exit code to 1 if total is not null
--benchmark measure processing speed
--testsuite=dir run regression tests from dir
--doctest run doctest on myself"
require 'docopt'
if __FILE__ == $0
options = Docopt(doc, '1.0.0') # parse options based on doc above
puts options.inspect
puts ARGV.inspect
endHell yeah! The option parser is generated based on doc string above, that you
pass to the Docopt function.
require 'docopt'
doc = "Usage: your_program.rb [options]
-h --help Show this.
-v --verbose Print more text.
--quiet Print less text.
-o FILE Specify output file [default: ./test.txt]"
options = Docopt(doc, version=nil, help=true)`
options['--help'] # returns true or false depending on option givenDocopt takes 1 required and 2 optional arguments:
-
docshould be a string that describes options in a human-readable format, that will be parsed to create the option parser. The simple rules of how to write such a docstring (in order to generate option parser from it successfully) are given in the next section. Here is a quick example of such a string:Usage: your_program.rb [options] -h --help Show this. -v --verbose Print more text. --quiet Print less text. -o FILE Specify output file [default: ./test.txt]. -
help, by defaulttrue, specifies whether the parser should automatically print the usage-message (supplied asdoc) in case-hor--helpoptions are encountered. After showing the usage-message, the program will terminate. If you want to handle-hor--helpoptions manually (as all other options), sethelp=false. -
version, by defaultnil, is an optional argument that specifies the version of your program. If supplied, then, if the parser encounters--versionoption, it will print the supplied version and terminate.versioncould be any printable object, but most likely a string, e.g.'2.1.0rc1'.
Note, when docopt is set to automatically handle -h, --help and
--version options, you still need to mention them in the options description
(doc) for your users to know about them.
The return value is an instance of the Docopt class:
doc = "Options:
--verbose
-o FILE Output file [default: out.txt]"
options = Docopt(doc)
puts options.inspect
# --verbose=nil
# -o="out.txt"You can access the values of options like a hash:
doc = "Options:
-v, --verbose Verbose output [default: true]
-o FILE Output file [default: out.txt]"
options = Docopt(doc)
# The following are equivilant:
puts options['-v']
puts options['--verbose']
puts options[:v]
puts options[:verbose]
You can access positional arguments in ARGV.
The main idea behind docopt is that a good usage-message (that describes
options and defaults unambiguously) is enough to generate an option parser.
Here are the simple rules (that you probably already follow) for your usage-message to be parsable:
-
Every line that starts with
-or--(not counting spaces) is treated as an option description, e.g.:Options: --verbose # GOOD -o FILE # GOOD Other: --bad # BAD, line does not start with dash "-" -
To specify that an option has an argument, put a word describing that argument after space (or equals
=sign) as shown below. You can use comma if you want to separate options. In the example below both lines are valid, however you are recommended to stick to a single style.-o FILE --output=FILE # without comma, with "=" sign -i <file>, --input <file> # with comma, wihtout "=" sing -
Use two spaces to separate options with their informal description.
--verbose More text. # BAD, will be treated as if verbose option had # an argument "More", so use 2 spaces instead -q Quit. # GOOD -o FILE Output file. # GOOD --stdout Use stdout. # GOOD, 2 spaces -
If you want to set a default value for an option with an argument, put it into the option description, in form
[default: <my-default-value>].-i INSTANCE Instance of something [default: 1] --coefficient=K The K coefficient [default: 2.95] --output=FILE Output file [default: test.txt] --directory=DIR Some directory [default: ./]
Something missing? Help porting docopt to Ruby!
In order to maintain your program's compatibility with future versions
of docopt.rb (as porting more features continues) you are recommended to
keep the following in the begining of doc argument:
Usage: my_program.rb [options] <arguments>...
or
Usage: my_program.rb [options] <argument>
or
Usage: my_program.rb [options]
(followed by an empty line), where you are free to change my_program.rb
and argument(s) name inside of <...>.
