Расширение Scopt OptionParser в Scala
Я пытаюсь иметь парсер базовых опций с некоторыми параметрами по умолчанию.
В других проектах я хотел бы расширить парсер опций другими параметрами.
Что-то вроде:
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)
}
}
Я новичок в Scala
и я не уверен, как теперь я могу использовать оба из них на одном args
,
я использую Scala
2.10 с scopt_2.10
v3.3.0.
1 ответ
Я открыл https://github.com/scopt/scopt/issues/132.
Пока что лучшее из того, что я смог придумать, это объединение двух парсеров.
case class OutputOpts(
val outputOption: Int = 1
)
trait OptsWithOutput {
def output: OutputOpts
}
Парсер для этого живет в родительском классе.
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"))
}
Дочерний класс теперь может использовать это:
case class ChildOpts(
childThing: Int = 42,
output: OutputOpts = OutputOpts()
) extends OptsWithOutput
И его парсер сочетает в себе два.
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"))
Обратите внимание, как мы должны установить errorOnUnknownArgument
в false
, что, безусловно, не идеально и вызывает предупреждения.