2011-09-22 10 views
3

저는 스칼라 유틸리티 응용 프로그램에서 명령 줄 구문 분석을 위해 Apache Commons CLI를 사용하고 있습니다. 인수 중 하나는 기본값 "5432"(PostgreSQL의 경우)를 대체하는 데이터베이스 포트 번호 (--port=)입니다. 유효성 검사를 돕기 위해 Option 클래스를 사용하려고합니다. 다음은 내가 생각해 낸 코드입니다. 유효성 검사를 수행하는 더 좋은 방법이 있습니까?스칼라 옵션을 사용하여 명령 줄 인수 확인

val port = Option(commandLine.getOptionValue("port", "5432")) map { 
    try { 
    val value = Integer.parseInt(_) 
    if (value < 1 || value > 65535) throw new NumberFormatException 
    value 
    } catch { 
    case ex: NumberFormatException => 
     throw new 
     IllegalArgumentException("the port argument must be a number between 1 and 65535") 
    } 
} get 

포트 번호는 1과 65535 사이의 정수 여야합니다.

이렇게하는 것이 좋을까요? 그 이유는 무엇? 나는 당신이 경우 무언가에 던져 질하고 싶은, 100 % 확실하지 않다 인정

val port = Option(commandLine.getOptionValue("port")) map { 
    try { 
    val value = Integer.parseInt(_) 
    if (value < 1 || value > 65535) throw new NumberFormatException 
    value 
    } catch { 
    case ex: NumberFormatException => 
     throw new 
     IllegalArgumentException("the port argument must be a number between 1 and 65535") 
    } 
} getOrElse(5432) 
+1

std lib에서 누락 된 것은'String => Option [Int]'입니다. – ziggystar

+2

@ziggystar : Scalaz를 사용할 수 있다면, 그것은'parsent : String => Validation [NumberFormatException, Int]'메소드를 가지고 있습니다. 유효성 검사에서'toOption'을 호출하면'Option [Int]'를 얻을 수 있습니다. – missingfaktor

답변

5

은 잘못, 또는 5432 경우 모든 잘못된 값에 대한 기본 포트이지만, 여기에 내가 무엇을 할 것이라고입니다 :

def getPort(candidate: Option[String]) = candidate 
    .map { _.toInt } // throws NumberFormatException 
    .filter { v => v > 0 && v <= 65535 } // returns Option[Int] 
    .getOrElse { throw new IllegalArgumentException("error message") } // return an Int or throws an exception 
+0

필자는 처음에'map (_. toInt)'와 비슷한 것을 가지고 있었지만 오류 메시지를 복제하고 싶지 않았습니다. – Ralph

+0

포트가 불법 인 경우 코드가 예외를 throw해야한다고 생각합니다. 포트가 제공되지 않으면 5432 만 사용해야합니다. – Ralph

+2

다음과 같이 주어진 메소드를 기본값으로 정의 할 수 있습니다 :'def getPort (candidate : Option [String] = Some ("5432")) = ...' – agilesteel

2

내가 유효성 검사를 시도해 보는 것이 좋습니다.

import scalaz._ 
import Scalaz._ 

val port = { 
    def checkRange(port: Int): Validation[String, Int] = { 
    if (port < 1 || port > 65535) "port not in [1-65535]".fail 
    else port.success 
    } 
    commandLine.getOptionValue("port", "5432") 
    .parseInt.flatMap(checkRange) match { 
    case Failure(e) => throw new IllegalArgumentException(e.toString) 
    case Success(port) => port 
    } 
}