2011-09-22 56 views
3

我正在使用Apache commons CLI在Scala实用程序应用程序中进行命令行分析。其中一个参数是覆盖缺省“5432”(用于PostgreSQL)的数据库端口号(--port=)。我正在尝试使用Option类来协助验证。这是我想出的代码。有没有更好的方法来进行验证?使用Scala选项来验证命令行参数

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(含)之间的整数。

这样做会更好吗?为什么或者为什么不?

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

我在标准库中缺少的是'String => Option [Int]'方法。 – ziggystar

+2

@ziggystar:如果你可以使用Scalaz,它有一个方法'parsent:String => Validation [NumberFormatException,Int]'。在验证中调用'toOption'会给你'Option [Int]'。 – missingfaktor

回答

5

我承认我不是100%肯定,你想在什么情况下被抛出什么不顺心,或者如果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

我认为如果端口非法,代码应该抛出异常。如果没有提供端口,它应该只使用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 
    } 
}