Ruby语法糖,仅用于核心参数解析



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

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

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

  • 我讨厌argn废话
  • 我讨厌if/-。*=/后面跟着每个单独的开关
  • each_with_index不会真正完成我正在寻找的开关可以嵌入在任何地方的非切换参数

如果我们满足"干净、核心、直观"的要求,可以完全修改。

感谢和干杯——Reed

您考虑过使用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

我自己的迭代:

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

编辑:越来越好了

最新更新