Ruby Option Parser。这段代码有可能更简洁吗?

时间:2014-08-18 21:04:27

标签: ruby

我编写了一个包含多个命令行选项的工作脚本。我想做一些这些选项所需的选项。我的研究让我得到以下代码。您将在脚本的末尾看到我正在单独检查是否已提供选项。

在python中,argparse模块有一个参数“required = True”,如果提供了给定的参数,它将自动退出程序。我在ruby模块中找不到类似的东西。是否有一个不同的,更高级的参数解析模块?是否有更简洁的方法来编写此代码?

options = {}

optparse = OptionParser.new do |opts|
  opts.banner = "\nUsage: How to use the code"
  opts.on('--debug',
      "Change log level to debug. Default is INFO") do |l|
    options[:debug] = l
  end

  options[:logfile] = "stage_refresh.out"
  opts.on('-l', '--logfile LOGFILE', "Logfile to log results. Default is stage_refresh.out") do |l|
    options[:source] = l
  end

  options[:source] = "localhost"
  opts.on('-s', '--source SOURCE_HOST', "Source host for dump. Default is localhost") do |s|
    options[:source] = s
  end

  opts.on('-t', '--target TARGET', "Target host to refresh. Must specify.") do |t|
    options[:target] = t
  end
end

optparse.parse!

unless options[:source_pass]
  puts "Must have --source_pass PASSWORD"
end

unless options[:target]
  puts "Must have --target TARGET_SERVER"
end

if options[:debug]
  logger.level = Logger::DEBUG
else
  logger.level = Logger::INFO
end

puts options[:source_pass]
puts options[:target]

.................

4 个答案:

答案 0 :(得分:0)

您可能会对trollop gem感兴趣。它有长/短选项,默认值,必需的标志等。使用它与你现在没有什么不同。

答案 1 :(得分:0)

OptionParser不是很优雅。

在ruby stdlib中也有GetOptLang,但它也不是很好。

存在slop和trollop,也是... ...

令人讨厌的是,ruby本身无法就这个问题找到一个非常优雅的解决方案。

我自己实际上最终直接解析了ARGV(虽然传递给了一个将为我处理命令行解析的方法)。

我大部分时间都不需要这样的东西:

- set_base_dir / tmp

所以没关系。但是更高级的命令行脚本需要它,所以我通常最终使用OptionParser,但在其中,我调用主应用程序中处理这些东西的方法。我只使用OptionParser作为我得到的--set_foo额外的东西。

答案 2 :(得分:0)

您可以使用Thor来简单轻松地编写CLI工具。

答案 3 :(得分:0)

我同意OptionParser有点冗长。我建议Slop。在所有选项listed in the Ruby Toolbox(按流行度排序)中,它似乎最接近您要查找的界面。它专门写成比OptionParser更简洁。

用法示例(来自自述文件):

opts = Slop.parse do
  banner 'Usage: foo.rb [options]'

  on 'name=', 'Your name'
  on 'p', 'password', 'An optional password', argument: :optional
  on 'v', 'verbose', 'Enable verbose mode'
end

# if ARGV is `--name Lee -v`
opts.verbose?  #=> true
opts.password? #=> false
opts[:name]    #=> 'lee'
opts.to_hash   #=> {:name=>"Lee", :password=>nil, :verbose=>true}