ruby语法糖只用于核心arg解析

时间:2011-10-07 04:19:17

标签: ruby arguments

用于计算非开关参数的语法糖?

argn = 0
ARGV.each do |arg|
   mission = Mission_DB.new unless mission
   if(arg.match(/^\-.*=/)) then
      fsav = arg.split('=')[1]                     if arg.match(/\-save=/)
      skip = arg.split('=')[1].split(',')          if arg.match(/\-skip=/)
      mission.mission = arg.split('=')[1].downcase if arg.match(/\-mission=/)
   else
      argn += 1
      mission.parseP1SCLRV(arg)                    if argn == 1
      template = arg                               if argn == 2
      mission.parseP1SCLRVPLV(arg)                 if argn == 3
      mission.parseDbUserLimits(arg)               if argn == 4
   end
end

我试图找到一个可重用,干净的核心只有arg解析语法直观(没有注释可读)。这还不错......但它还不够好。

  • 我讨厌argn crap
  • 我讨厌if /-.*=/然后是每个单独的开关
  • each_with_index将无法真正实现我正在寻找的东西,因为交换机可以嵌入非切换args中的任何位置

如果我们正在满足“干净,核心,直观”的要求,请随意完全改造。

谢谢和干杯 - 励志

2 个答案:

答案 0 :(得分:4)

您是否考虑过使用optparse?它附带了Ruby标准库。

这是一个使用optparse对示例中的参数进行选项解析的类。它处理错误,在给出“-h”或“--help”时打印其用法,并将解析后的参数封装到一个可以传递的好类中:

require 'optparse'

class Arguments

  POSITIONAL_ARGS = %w(p1sclrv template p1sclrvplv db_user_limits)

  attr_reader :mission
  attr_reader :save_path
  attr_reader :what_to_skip
  attr_reader *POSITIONAL_ARGS

  def initialize(argv)
    option_parser.parse!(argv)
    POSITIONAL_ARGS.each do |positional_arg|
      value = argv.shift
      instance_variable_set("@#{positional_arg}", value)
      raise OptionParser::MissingArgument, positional_arg.to_s unless value
    end
    raise OptionParser::NeedlessArgument, argv.first unless argv.empty?
  rescue OptionParser::ParseError => e
    puts e
    puts option_parser
    exit(1)
  end

  private

  def option_parser
    OptionParser.new do |op|
      op.banner += ' ' + POSITIONAL_ARGS.join(' ')
      op.on('--save=PATH', 'Save to PATH') do |value|
        @save_path = value
      end
      op.on('--skip=WHAT', 'Skip WHAT') do |value|
        @what_to_skip = value
      end
      op.on('--mission=NAME', 'Do mission NAME') do |value|
        @mission = value
      end
    end
  end

end

在实际使用中,将ARGV传递给它:

args = Arguments.new(ARGV)

这是一个传递一个伪造的ARGV并打印解析的参数的例子:

args = Arguments.new(%w(--skip=FOO alpha bravo charley delta))
p args.p1sclrv            # => "alpha"
p args.template           # => "bravo"
p args.p1sclrvplv         # => "charley"
p args.db_user_limits     # => "delta"
p args.mission            # => nil
p args.save_path          # => nil
p args.what_to_skip       # => "FOO"

这是帮助的样子:

Arguments.new(%w(--help))
# => Usage: foo [options] p1sclrv template p1sclrvplv db_user_limits
# =>         --save=PATH                  Save to PATH
# =>         --skip=WHAT                  Skip WHAT
# =>         --mission=NAME               Do mission NAME

答案 1 :(得分:0)

我自己的迭代:

fsav = nil
skip = []
template = p1sclrv = p1sclrvplv = dbuserlimits = nil
ARGV.each do |arg|
   case arg
      when /\-save=/    then fsav = arg.split('=')[1]
      when /\-skip=/    then skip = arg.split('=')[1].split(',')
      when /\-mission=/ then mission.mission = arg.split('=')[1].downcase
   else
      unless(p1sclrv)      then p1sclrv = arg;      next; end
      unless(template)     then template = arg;     next; end
      unless(p1sclrvplv)   then p1sclrvplv = arg;   next; end
      unless(dbuserlimits) then dbuserlimits = arg; next; end
   end
end

编辑:变得更好。