本文简要介绍ruby语言中 OptionParser类
的用法。
OptionParser
OptionParser 的新手?
请参阅 Tutorial 。
介绍
OptionParser
是一个用于命令行选项分析的类。它比 GetoptLong
更先进,但也更易于使用,并且是一个更 Ruby-oriented 的解决方案。
特征
-
参数说明和处理它的代码写在同一个地方。
-
它可以输出一个选项摘要;你不需要单独维护这个字符串。
-
可选和强制参数的指定非常优雅。
-
参数可以自动转换为指定的类。
-
参数可以限制在某个集合中。
所有这些函数都在下面的示例中进行了演示。有关完整文档,请参阅 make_switch
。
最小的例子
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
end.parse!
p options
p ARGV
生成帮助
OptionParser
可用于为您编写的命令自动生成帮助:
require 'optparse'
Options = Struct.new(:name)
class Parser
def self.parse(options)
args = Options.new("world")
opt_parser = OptionParser.new do |parser|
parser.banner = "Usage: example.rb [options]"
parser.on("-nNAME", "--name=NAME", "Name to say hello to") do |n|
args.name = n
end
parser.on("-h", "--help", "Prints this help") do
puts parser
exit
end
end
opt_parser.parse!(options)
return args
end
end
options = Parser.parse %w[--help]
#=>
# Usage: example.rb [options]
# -n, --name=NAME Name to say hello to
# -h, --help Prints this help
必需的参数
对于需要参数的选项,选项规范字符串可能包含全部大写的选项名称。如果在没有所需参数的情况下使用选项,则会引发异常。
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!
用过的:
$ ruby optparse-test.rb -r optparse-test.rb:9:in `<main>': missing argument: -r (OptionParser::MissingArgument) $ ruby optparse-test.rb -r my-library You required my-library!
类型强制
OptionParser
支持将命令行参数强制转换为我们的对象的能力。
OptionParser
带有一些 ready-to-use 类型的强制转换。他们是:
-
Date
-Date.parse
接受的任何内容 -
DateTime
-DateTime.parse
接受的任何内容 -
Time
-Time.httpdate
或Time.parse
接受的任何内容 -
URI
-URI.parse
接受的任何内容 -
Shellwords
-Shellwords.shellwords
接受的任何内容 -
String
- 任何非空字符串 -
Integer
- 任何整数。将转换八进制。 (例如 124、-3、040) -
Float
- 任何浮点数。 (例如 10、3.14、-100E+13) -
Numeric
- 任何整数、浮点数或有理数(1、3.4、1/3) -
DecimalInteger
- 与Integer
类似,但没有八进制格式。 -
OctalInteger
- 与Integer
类似,但没有十进制格式。 -
DecimalNumeric
- 十进制整数或浮点数。 -
TrueClass
- 接受‘+, yes, true, -, no, false’,默认为true
-
FalseClass
- 与TrueClass
相同,但默认为false
-
Array
- 以‘,’分隔的字符串(例如 1,2,3) -
Regexp
- 正则表达式。还包括选项。
我们还可以添加我们自己的强制,我们将在下面介绍。
使用内置转换
例如,使用内置的Time
转换。其他内置转换的行为方式相同。 OptionParser
将尝试将参数解析为 Time
。如果成功,该时间将传递给处理程序块。否则,将引发异常。
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!
用过的:
$ ruby optparse-test.rb -t nonsense ... invalid argument: -t nonsense (OptionParser::InvalidArgument) $ ruby optparse-test.rb -t 10-11-12 2010-11-12 00:00:00 -0500 $ ruby optparse-test.rb -t 9:30 2014-08-13 09:30:00 -0400
创建自定义转换
OptionParser
上的accept
方法可用于创建转换器。它指定在指定类时调用哪个转换块。下面的示例使用它在 on
处理程序接收它之前获取 User
对象。
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!
用过的:
$ ruby optparse-test.rb --user 1 #<struct User id=1, name="Sam"> $ ruby optparse-test.rb --user 2 #<struct User id=2, name="Gandalf"> $ ruby optparse-test.rb --user 3 optparse-test.rb:15:in `block in find_user': No User Found for id 3 (RuntimeError)
将选项存储到 Hash
order
、parse
等方法的 into
选项将命令行选项存储到 Hash
中。
require 'optparse'
options = {}
OptionParser.new do |parser|
parser.on('-a')
parser.on('-b NUM', Integer)
parser.on('-v', '--verbose')
end.parse!(into: options)
p options
用过的:
$ ruby optparse-test.rb -a {:a=>true} $ ruby optparse-test.rb -a -v {:a=>true, :verbose=>true} $ ruby optparse-test.rb -a -b 100 {:a=>true, :b=>100}
完整示例
下面的例子是一个完整的 Ruby 程序。您可以运行它并查看指定各种选项的效果。这可能是学习 optparse
函数的最佳方式。
require 'optparse'
require 'optparse/time'
require 'ostruct'
require 'pp'
class OptparseExample
Version = '1.0.0'
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, :extension, :delay, :time, :record_separator,
:list
def initialize
self.library = []
self.inplace = false
self.encoding = "utf8"
self.transfer_type = :auto
self.verbose = false
end
def define_options(parser)
parser.banner = "Usage: example.rb [options]"
parser.separator ""
parser.separator "Specific options:"
# add additional options
perform_inplace_option(parser)
delay_execution_option(parser)
execute_at_time_option(parser)
specify_record_separator_option(parser)
list_example_option(parser)
specify_encoding_option(parser)
optional_option_argument_with_keyword_completion_option(parser)
boolean_verbose_option(parser)
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
# Another typical switch to print the version.
parser.on_tail("--version", "Show version") do
puts Version
exit
end
end
def perform_inplace_option(parser)
# Specifies an optional option argument
parser.on("-i", "--inplace [EXTENSION]",
"Edit ARGV files in place",
"(make backup if EXTENSION supplied)") do |ext|
self.inplace = true
self.extension = ext || ''
self.extension.sub!(/\A\.?(?=.)/, ".") # Ensure extension begins with dot.
end
end
def delay_execution_option(parser)
# Cast 'delay' argument to a Float.
parser.on("--delay N", Float, "Delay N seconds before executing") do |n|
self.delay = n
end
end
def execute_at_time_option(parser)
# Cast 'time' argument to a Time object.
parser.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
self.time = time
end
end
def specify_record_separator_option(parser)
# Cast to octal integer.
parser.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
"Specify record separator (default \\0)") do |rs|
self.record_separator = rs
end
end
def list_example_option(parser)
# List of arguments.
parser.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
self.list = list
end
end
def specify_encoding_option(parser)
# 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|
self.encoding = encoding
end
end
def optional_option_argument_with_keyword_completion_option(parser)
# Optional '--type' option argument with keyword completion.
parser.on("--type [TYPE]", [:text, :binary, :auto],
"Select transfer type (text, binary, auto)") do |t|
self.transfer_type = t
end
end
def boolean_verbose_option(parser)
# Boolean switch.
parser.on("-v", "--[no-]verbose", "Run verbosely") do |v|
self.verbose = v
end
end
end
#
# Return a structure describing the options.
#
def parse(args)
# The options specified on the command line will be collected in
# *options*.
@options = ScriptOptions.new
@args = OptionParser.new do |parser|
@options.define_options(parser)
parser.parse!(args)
end
@options
end
attr_reader :parser, :options
end # class OptparseExample
example = OptparseExample.new
options = example.parse(ARGV)
pp options # example.options
pp ARGV
shell Completion
对于现代 shell(例如 bash、zsh 等),您可以将 shell 补全用于命令行选项。
更多文件
上述示例以及随附的 Tutorial 应该足以学习如何使用此类。如果您有任何问题,请在 bugs.ruby-lang.org 提交票证。
相关用法
- Ruby OptionParser.reject用法及代码示例
- Ruby OptionParser.getopts用法及代码示例
- Ruby OptionParser.accept用法及代码示例
- Ruby Option.level用法及代码示例
- Ruby Option.byte用法及代码示例
- Ruby Option.family用法及代码示例
- Ruby Option.int用法及代码示例
- Ruby Option.new用法及代码示例
- Ruby Option.ipv4_multicast_loop用法及代码示例
- Ruby Option.inspect用法及代码示例
- Ruby Option.bool用法及代码示例
- Ruby Option.to_s用法及代码示例
- Ruby Option.unpack用法及代码示例
- Ruby Option.optname用法及代码示例
- Ruby Option.ipv4_multicast_ttl用法及代码示例
- Ruby Options类用法及代码示例
- Ruby Option.data用法及代码示例
- Ruby Option.linger用法及代码示例
- Ruby Open3.capture3用法及代码示例
- Ruby Open3.capture2用法及代码示例
- Ruby OpenStruct.ostruct[name] =用法及代码示例
- Ruby OpenSSL.fips_mode =用法及代码示例
- Ruby OpenSSL模块用法及代码示例
- Ruby Open3.capture2e用法及代码示例
- Ruby Open3.popen2e用法及代码示例
注:本文由纯净天空筛选整理自ruby-lang.org大神的英文原创作品 OptionParser类。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。