summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-12 04:37:12 +0000
committerhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-12 04:37:12 +0000
commitae0e6807696b3c7b3372619ec6408dfe83333210 (patch)
treee03d05bb6f9402eb31d7336e21d11691374c3172 /lib
parent2f7e05b1b54db0129d8f6d2a9a4a60271d71821b (diff)
* lib/optparse.rb: improvements for OptionParser documentation.
[misc #10608][ruby-core:66901][ci skip] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49218 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/optparse.rb295
1 files changed, 218 insertions, 77 deletions
diff --git a/lib/optparse.rb b/lib/optparse.rb
index 4ec891e3ae..992dd8b28a 100644
--- a/lib/optparse.rb
+++ b/lib/optparse.rb
@@ -117,8 +117,120 @@
# #=>
# # Usage: example.rb [options]
# # -n, --name=NAME Name to say hello to
-# # -h, --help Prints this help#
+# # -h, --help Prints this help
#
+# === Required Arugments
+#
+# For options that require an argument, option specification strings may include an
+# option name in all caps. If an option is used without the required argument,
+# an exception will be raised.
+# require 'optparse'
+#
+# options = {}
+# OptionParser.new do |parser|
+# parser.on("-r", "--require LIBRARY",
+# "Require the LIBRARY before executing your script") do |lib|
+# puts "You required #{lib}!"
+# end
+# end.parse!
+#
+# Used:
+#
+# bash-3.2$ ruby optparse-test.rb -r
+# optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument)
+# bash-3.2$ ruby optparse-test.rb -r my-library
+# You required my-library!
+#
+# === Type Coercion
+#
+# OptionParser supports the ability to coerce command line arguments
+# into objects for us.
+#
+# OptionParser comes with a few ready-to-use kinds of type
+# coercion. They are:
+#
+# - Date -- Anything accepted by +Date.parse+
+# - DateTime -- Anything accepted by +DateTime.parse+
+# - Time -- Anyting accepted by +Time.httpdate+ or +Time.parse+
+# - URI -- Anything accepted by +URI.parse+
+# - Shellwords -- Anything accepted by +Shellwords.shellwords+
+# - String -- Any non-empty string
+# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
+# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
+# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
+# - DecimalInteger -- Like +Integer+, but no octal format.
+# - OctalInteger -- Like +Integer+, but no decimal format.
+# - DecimalNumeric -- Decimal integer or float.
+# - TrueClass -- Accepts '+, yes, true, -, no, false' and
+# defaults as +true+
+# - FalseClass -- Same as +TrueClass+, but defaults to +false+
+# - Array -- Strings separated by ',' (e.g. 1,2,3)
+# - Regexp -- Regular expressions. Also includes options.
+#
+# We can also add our own coercions, which we will cover soon.
+#
+# ==== Using Built-in Conversions
+#
+# As an example, the built-in +Time+ conversion is used. The other built-in
+# conversions behave in in the same way.
+# OptionParser will attempt to parse the argument
+# as a +Time+. If it succeeeds, that time will be passed to the
+# handler block. Otherwise, an exception will be raised.
+#
+# require 'optparse'
+# require 'optparse/time'
+# OptionParser.new do |parser|
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# p time
+# end
+# end.parse!
+#
+# Used:
+# bash-3.2$ ruby optparse-test.rb -t nonsense
+# ... invalid argument: -t nonsense (OptionParser::InvalidArgument)
+# from ... time.rb:5:in `block in <top (required)>'
+# from optparse-test.rb:31:in `<main>'
+# bash-3.2$ ruby optparse-test.rb -t 10-11-12
+# 2010-11-12 00:00:00 -0500
+# bash-3.2$ ruby optparse-test.rb -t 9:30
+# 2014-08-13 09:30:00 -0400
+#
+# ==== Creating Custom Conversions
+#
+# The +accept+ method on OptionParser may be used to create converters.
+# It specifies which conversion block to call whenever a class is specified.
+# The example below uses it to fetch a +User+ object before the +on+ handler receives it.
+#
+# require 'optparse'
+#
+# User = Struct.new(:id, :name)
+#
+# def find_user id
+# not_found = ->{ raise "No User Found for id #{id}" }
+# [ User.new(1, "Sam"),
+# User.new(2, "Gandalf") ].find(not_found) do |u|
+# u.id == id
+# end
+# end
+#
+# op = OptionParser.new
+# op.accept(User) do |user_id|
+# find_user user_id.to_i
+# end
+#
+# op.on("--user ID", User) do |user|
+# puts user
+# end
+#
+# op.parse!
+#
+# output:
+# bash-3.2$ ruby optparse-test.rb --user 1
+# #<struct User id=1, name="Sam">
+# bash-3.2$ ruby optparse-test.rb --user 2
+# #<struct User id=2, name="Gandalf">
+# bash-3.2$ ruby optparse-test.rb --user 3
+# optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
# === Complete example
#
# The following example is a complete Ruby program. You can run it and see the
@@ -131,108 +243,137 @@
# require 'pp'
#
# class OptparseExample
-#
# CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
# CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
#
+# class ScriptOptions
+# attr_accessor :library, :inplace, :encoding, :transfer_type,
+# :verbose
+# def initialize
+# self.library = []
+# self.inplace = false
+# self.encoding = "utf8"
+# self.transfer_type = :auto
+# self.verbose = false
+# end
+# end
+#
# #
# # Return a structure describing the options.
# #
# def self.parse(args)
-# # The options specified on the command line will be collected in *options*.
-# # We set default values here.
-# options = OpenStruct.new
-# options.library = []
-# options.inplace = false
-# options.encoding = "utf8"
-# options.transfer_type = :auto
-# options.verbose = false
+# # The options specified on the command line will be collected in
+# # *options*.
#
-# opt_parser = OptionParser.new do |opts|
-# opts.banner = "Usage: example.rb [options]"
+# @options = ScriptOptions.new
+# option_parser.parse!(args)
+# @options
+# end
#
-# opts.separator ""
-# opts.separator "Specific options:"
+# attr_reader :parser, :options
#
-# # Mandatory argument.
-# opts.on("-r", "--require LIBRARY",
-# "Require the LIBRARY before executing your script") do |lib|
-# options.library << lib
-# end
+# def option_parser
+# @parser ||= OptionParser.new do |parser|
+# parser.banner = "Usage: example.rb [options]"
+# parser.separator ""
+# parser.separator "Specific options:"
#
-# # Optional argument; multi-line description.
-# opts.on("-i", "--inplace [EXTENSION]",
-# "Edit ARGV files in place",
-# " (make backup if EXTENSION supplied)") do |ext|
-# options.inplace = true
-# options.extension = ext || ''
-# options.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
-# end
+# # add additional options
+# perform_inplace_option
+# delay_execution_option
+# execute_at_time_option
+# specify_record_separator_option
+# list_example_option
+# specify_encoding_option
+# optional_option_argument_with_keyword_completion_option
+# boolean_verbose_option
#
-# # Cast 'delay' argument to a Float.
-# opts.on("--delay N", Float, "Delay N seconds before executing") do |n|
-# options.delay = n
+# parser.separator ""
+# parser.separator "Common options:"
+# # No argument, shows at tail. This will print an options summary.
+# # Try it and see!
+# parser.on_tail("-h", "--help", "Show this message") do
+# puts parser
+# exit
# end
-#
-# # Cast 'time' argument to a Time object.
-# opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
-# options.time = time
+# # Another typical switch to print the version.
+# parser.on_tail("--version", "Show version") do
+# puts ::Version.join('.')
+# exit
# end
+# end
+# end
#
-# # Cast to octal integer.
-# opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
-# "Specify record separator (default \\0)") do |rs|
-# options.record_separator = rs
-# end
+# def perform_inplace_option
+# # Specifies an optional option argument
+# parser.on("-i", "--inplace [EXTENSION]",
+# "Edit ARGV files in place",
+# " (make backup if EXTENSION supplied)") do |ext|
+# options.inplace = true
+# options.extension = ext || ''
+# options.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
+# end
+# end
#
-# # List of arguments.
-# opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
-# options.list = list
-# end
+# def delay_execution_option
+# # Cast 'delay' argument to a Float.
+# parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
+# options.delay = n
+# end
+# end
#
-# # Keyword completion. We are specifying a specific set of arguments (CODES
-# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
-# # the shortest unambiguous text.
-# code_list = (CODE_ALIASES.keys + CODES).join(',')
-# opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
-# " (#{code_list})") do |encoding|
-# options.encoding = encoding
-# end
+# def execute_at_time_option
+# # Cast 'time' argument to a Time object.
+# parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
+# options.time = time
+# end
+# end
#
-# # Optional argument with keyword completion.
-# opts.on("--type [TYPE]", [:text, :binary, :auto],
-# "Select transfer type (text, binary, auto)") do |t|
-# options.transfer_type = t
-# end
#
-# # Boolean switch.
-# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
-# options.verbose = v
-# end
+# def specify_record_separator_option
+# # Cast to octal integer.
+# parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
+# "Specify record separator (default \\0)") do |rs|
+# options.record_separator = rs
+# end
+# end
#
-# opts.separator ""
-# opts.separator "Common options:"
+# def list_example_option
+# # List of arguments.
+# parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
+# options.list = list
+# end
+# end
#
-# # No argument, shows at tail. This will print an options summary.
-# # Try it and see!
-# opts.on_tail("-h", "--help", "Show this message") do
-# puts opts
-# exit
-# end
+# def specify_encoding_option
+# # Keyword completion. We are specifying a specific set of arguments (CODES
+# # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
+# # the shortest unambiguous text.
+# code_list = (CODE_ALIASES.keys + CODES).join(',')
+# parser.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
+# " (#{code_list})") do |encoding|
+# options.encoding = encoding
+# end
+# end
#
-# # Another typical switch to print the version.
-# opts.on_tail("--version", "Show version") do
-# puts ::Version.join('.')
-# exit
-# end
+#
+# def optional_option_argument_with_keyword_completion_option
+# # Optional '--type' option argument with keyword completion.
+# parser.on("--type [TYPE]", [:text, :binary, :auto],
+# "Select transfer type (text, binary, auto)") do |t|
+# options.transfer_type = t
# end
+# end
#
-# opt_parser.parse!(args)
-# options
-# end # parse()
#
-# end # class OptparseExample
+# def boolean_verbose_option
+# # Boolean switch.
+# parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+# options.verbose = v
+# end
+# end
#
+# end # class OptparseExample
# options = OptparseExample.parse(ARGV)
# pp options
# pp ARGV