2011-10-07 62 views
0

用於計算非開關參數的語法糖?紅寶石語法糖只用於核心arg解析

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
  • 我最討厭的,如果/-.*=/其次是每個個體開關
  • each_with_index不會真正完成我正在尋找的開關可在任何地方嵌入在非切換參數內

只要我們能夠滿足「乾淨,唯一核心,直觀」的要求,就可以完全改造。

感謝和歡呼聲--Reed

回答

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 

編輯:漸入佳境。

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 
+0

感謝您的介紹optparse ..我沒有看過它之前。我的挑戰是腳本最終會變成非編碼器類型,所以我需要儘可能保持語法上的簡單。運營商不喜歡運行他們不瞭解的代碼,但他們也不經常關心學習編碼。 –

+0

+1示例 – knut

+1

@Reed,使用該約束,消除所有開關參數並僅使用位置參數。然後它只是'foo = ARGV.shift','bar = ARGV.shift'等等。你寫的是代碼,就像使用optparse一樣。 「非編碼器」也沒有機會。對於這個問題,如果你的「非編碼員」熟悉shell腳本,那麼腳本應該用shell腳本編寫。 –