【问题标题】:How to use getoptlong class in ruby?如何在 ruby​​ 中使用 getoptlong 类?
【发布时间】:2011-04-16 18:39:07
【问题描述】:

我需要帮助在 Ruby 中使用 getoptlong 类。我需要执行命令 prog_name.ruby -u -i -s 文件名。到目前为止我只能用 prog_name.ruby -u filename -i filename -s filename 来执行它。

这是我的 getoptlong 代码:

require 'getoptlong'

class CommonLog
parser = GetoptLong.new
parser.set_options(["-h", "--help", GetoptLong::NO_ARGUMENT],
                   ["-u", "--url",  GetoptLong::NO_ARGUMENT],
                   ["-i", "--ip",   GetoptLong::NO_ARGUMENT],
                   ["-s", "--stat", GetoptLong::NO_ARGUMENT])

begin
  begin
      opt,arg = parser.get_option
      break if not opt

      case opt
         when "-h" || "--help"
           puts "Usage: -u  filename"
           puts "Usage: -i  filename"
           puts "Usage: -s  filename"
         exit
         when "-u" || "--url"
            log = CommonLog.new(ARGV[0])
            log.urlReport
         when "-i" || "--ip"
            log = CommonLog.new(ARGV[0])
            log.ipReport
         when "-s" || "--stat"
            log = CommonLog.new(ARGV[0])
            log.statReport
         end
      rescue => err
         puts "#{err.class()}: #{err.message}"
         puts "Usage: -h -u -i -s filename"
      exit
   end
end while 1

if ARGV[0] == nil || ARGV.size != 1
   puts "invalid! option and filename required"
   puts "usage: -h -u -i -s filename"
end

【问题讨论】:

  • begin/endbegin/end while 1 块内? o_O loop 怎么样?

标签: ruby getopt-long


【解决方案1】:

我将通过推荐查看新的“slop”gem 来回答。它是getoptlong 的包装。

如果您使用的是 RVM,则可以使用 gem install slop,否则可以使用 sudo gem install slop

GetOptLong 非常强大,但是虽然我已经用过几次了,但我还是要每次都去查看文档。

如果您想要更强大的功能,“比 GetOptLong 更易于使用的界面”,请查看 Ruby 的 OptionParser。您需要更好地制定逻辑,但这是转换代码的快速通道。我不得不为 CommonLog gem 存根一个类,因为我不使用它。重要的东西跟从ARGV 拉取日志的那一行:

require 'optparse'

class CommonLog
  def initialize(*args); end
  def urlReport();     puts "running urlReport()";        end
  def ipReport();      puts "running ipReport()";         end
  def statReport(arg); puts "running statReport(#{arg})"; end
end

log = CommonLog.new(ARGV[0])

OptionParser.new { |opts|
  opts.banner = "Usage: #{File.basename($0)} -u -i -s filename"

  opts.on( '-u', '--[no-]url', 'some short text describing URL') do
    log.urlReport()
  end

  opts.on('-i', '--[no-]ip', 'some short text describing IP') do
    log.ipReport()
  end

  opts.on('-s', '--stat FILENAME', 'some short text describing STAT') do |arg|
    log.statReport(arg)
  end
}.parse!

另外,作为一个快速的批评,你不是在编写惯用的 Ruby 代码:

  • when 语句可以写成:when "-h", "--help"
  • if ARGV[0] == nil || ARGV.size != 1 很复杂。研究 ARGV 和阵列的工作原理。通常情况下,ARGV[0] 为 nil 将不再有任何参数,因此 ARGV.empty? 可能就足够了。

【讨论】:

  • optparser > getoptlong。绝对。
【解决方案2】:

示例程序中有几个错误

  1. #each 和#get 只返回选项中的第一个字符串,并将其他字符串转换为它。
  2. 您应该在选项处理之前检查参数
  3. 您可能不希望在您的日志记录类中使用它
require 'getoptlong'
# don't pollute CommonLog with this
include CommonLog
# if this is the startup module
if __FILE__ == $0 then
  # Check to ensure there are arguments
  if ARGV.size < 1
    puts "invalid! option and filename required"
    puts "usage: -h -u -i -s filename"
  end
  # set up parser and get the options
  parser_opts=GetoptLong.new(
    ["--help", "-h", GetoptLong::NO_ARGUMENT],
    ["--url", "-u", GetoptLong::NO_ARGUMENT],
    ["--ip", "-i", "--ip", GetoptLong::NO_ARGUMENT],
    ["--stat", "-s", GetoptLong::NO_ARGUMENT]
  )

  parser_opts.each do |opt,arg|
    begin # this is for the exception processing
      case opt
      when "--help" #only the first option is returned read ruby doc on #each
        puts "Usage: -u  filename"
        puts "Usage: -i  filename"
        puts "Usage: -s  filename"
        exit
      when "--url" #only the first option is returned
        log = CommonLog.new(ARGV[0])
        log.urlReport
      when "--ip" #only the first option is returned
        log = CommonLog.new(ARGV[0])
        log.ipReport
      when "--stat" #only the first option is returned
        log = CommonLog.new(ARGV[0])
        log.statReport
      else # this should not be used
        puts "unexpected option %s"%opt 
        puts "Usage: -h -u -i -s filename"
      end
    rescue Exception => err #rescuing an unexpected Exception
      puts "#{err.class()}: #{err.message}"
      puts "Usage: -h -u -i -s filename"
      Kernel.exit
    end
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2014-05-01
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多