2011-10-07 2 views
0

논 스위치 args 계산을위한 구문 설탕?루비 syntactic 설탕 코어 전용 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 재사용, 깨끗한 코어를 찾기 위해 노력했습니다. 이것은 나쁘지는 않지만 그다지 좋지 않습니다.

  • 나는 각각의 스위치 다음에 경우 /-.*=/
  • 이 each_with_index은 정말 스위치는 어디 내장 될 수 있기 때문에 무엇을 찾고 있어요 달성하지 않습니다
  • 내가 싫어하는에서 argN 쓰레기를 싫어 전환되지 않은 인수 내에서

우리는 "깨끗하고 핵심적이고 직관적 인"요구 사항을 충족하는 경우 완전히 자유롭게 변경할 수 있습니다.

감사 건배 --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를 사용하여 예제에서 인수에 대한 옵션 구문 분석을 수행하는 클래스입니다. 실제 사용에서

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를 통과 : 그것은 당신이 주변에 통과 할 수있다 "--help" "-h"또는이 주어진다면 그 사용을 인쇄, 오류를 처리하고, 좋은 클래스로 해석 인수를 캡슐화 :

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를 사용하는 것처럼 코드이다. "비 코더 (non coder)"는 아무런 기회도 없습니다. 그 문제에 대해 "비 코더"가 셸 스크립팅에 익숙하다면 스크립트는 셸 스크립트로 작성해야합니다. –

관련 문제