当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Ruby OptionParser类用法及代码示例


本文简要介绍ruby语言中 OptionParser类 的用法。

OptionParser

OptionParser 的新手?

请参阅 Tutorial

介绍

OptionParser 是一个用于命令行选项分析的类。它比 GetoptLong 更先进,但也更易于使用,并且是一个更 Ruby-oriented 的解决方案。

特征

  1. 参数说明和处理它的代码写在同一个地方。

  2. 它可以输出一个选项摘要;你不需要单独维护这个字符串。

  3. 可选和强制参数的指定非常优雅。

  4. 参数可以自动转换为指定的类。

  5. 参数可以限制在某个集合中。

所有这些函数都在下面的示例中进行了演示。有关完整文档,请参阅 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.httpdateTime.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

orderparse 等方法的 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-lang.org大神的英文原创作品 OptionParser类。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。