简体   繁体   中英

Extending Scopt OptionParser in Scala

I'm trying to have a base option parser with some default parameters.

In other projects i would like to extend the option parser with other parameters.

Something like:

case class Config(foo: String = null)

trait DefaultParser { self: OptionParser[Config] =>
  opt[String]('f', "foo") action { (x, c) =>
    c.copy(foo = x)
  }
}

case class MyConfig(bar: String = "hello world")

trait MyParser { self: OptionParser[MyConfig] =>
  opt[String]('b', "bar") action { (x, c) =>
    c.copy(bar = x)
  }
}

I'm a newbie at Scala and I'm not sure how I can now use both of them on the same args .

I'm using Scala 2.10 with scopt_2.10 v3.3.0.

I've opened https://github.com/scopt/scopt/issues/132 .

So far the best of what I've been able to come up with is combining two parsers.

case class OutputOpts(
  val outputOption: Int = 1
)

trait OptsWithOutput {
  def output: OutputOpts
}

The parser for this lives in the parent class.

def parseOutputOpts(args: Array[String]): OutputOpts = {
  val parser = new scopt.OptionParser[OutputOpts]("scopt") {
    override def errorOnUnknownArgument = false

    opt[Int]("outputOption") action { (x, c) =>
      c.copy(outputOption = x)
    } text ("some output option")
  }

  parser.parse(args, OutputOpts())
    .getOrElse(throw new Exception("Error parsing output cli args"))
}

A child class now can use this:

case class ChildOpts(
  childThing: Int = 42,
  output: OutputOpts = OutputOpts()
) extends OptsWithOutput

And its parser combines the two.

val opts = ChildOpts(output = super.parseOutputOpts(args))

val parser = new scopt.OptionParser[ChildOpts]("scopt") {
  override def errorOnUnknownArgument = false

  opt[Int]("childThing") action { (x, c) =>
    c.copy(childThing = x)
  } text ("some child thing")
}

parser.parse(args, opts).getOrElse(throw new Exception("failed"))

Note how we have to set errorOnUnknownArgument to false , which is definitely not ideal and causes warnings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM