Best way to parse command-line parameters?

Eugene Yokota picture Eugene Yokota · Feb 23, 2010 · Viewed 130.9k times · Source

What's the best way to parse command-line parameters in Scala? I personally prefer something lightweight that does not require external jar.

Related:

Answer

pjotrp picture pjotrp · Jul 6, 2010

For most cases you do not need an external parser. Scala's pattern matching allows consuming args in a functional style. For example:

object MmlAlnApp {
  val usage = """
    Usage: mmlaln [--min-size num] [--max-size num] filename
  """
  def main(args: Array[String]) {
    if (args.length == 0) println(usage)
    val arglist = args.toList
    type OptionMap = Map[Symbol, Any]

    def nextOption(map : OptionMap, list: List[String]) : OptionMap = {
      def isSwitch(s : String) = (s(0) == '-')
      list match {
        case Nil => map
        case "--max-size" :: value :: tail =>
                               nextOption(map ++ Map('maxsize -> value.toInt), tail)
        case "--min-size" :: value :: tail =>
                               nextOption(map ++ Map('minsize -> value.toInt), tail)
        case string :: opt2 :: tail if isSwitch(opt2) => 
                               nextOption(map ++ Map('infile -> string), list.tail)
        case string :: Nil =>  nextOption(map ++ Map('infile -> string), list.tail)
        case option :: tail => println("Unknown option "+option) 
                               exit(1) 
      }
    }
    val options = nextOption(Map(),arglist)
    println(options)
  }
}

will print, for example:

Map('infile -> test/data/paml-aln1.phy, 'maxsize -> 4, 'minsize -> 2)

This version only takes one infile. Easy to improve on (by using a List).

Note also that this approach allows for concatenation of multiple command line arguments - even more than two!