1

I'm working on a command line tool written in Scala which is executed as:

sbt "run --customerAccount 1234567"

Now, I wish to make this flexible to accept "--CUSTOMERACCOUNT" or --cUsToMerAccount or --customerACCOUNT ...you get the drift

Here's what the code looks like:

lazy val OptionsParser: OptionParser[Args] = new scopt.OptionParser[Args]("scopt") {
    head(
      "XML Generator",
      "Creates XML for testing"
    )
    help("help").text(s"Prints this usage message. $envUsage")

    opt[String]('c', "customerAccount")
      .text("Required: Please provide customer account number as -c 12334 or --customerAccount 12334")
      .required()
      .action { (cust, args) =>
        assert(cust.nonEmpty, "cust is REQUIRED!!")
        args.copy(cust = cust)
      }
}

I assume the opt[String]('c', "customerAccount") does the pattern matching from the command line and will match with "customerAccount" - how do I get this to match with "--CUSTOMERACCOUNT" or --cUsToMerAccount or --customerACCOUNT? What exactly does the args.copy (cust = cust) do?

I apologize if the questions seem too basic. I'm incredibly new to Scala, have worked in Java and Python earlier so sometimes I find the syntax a little hard to understand as well.

4

1 回答 1

3

您通常会使用以下代码解析 args:

OptionsParser.parse(args, Args())

因此,如果您想要不区分大小写,可能最简单的方法是args使用类似

val canonicalized = args.map(_.toLowerCase)

OptionsParser.parse(canonicalized, Args())

或者,例如,如果您只想规范化--以 bare 开头和之前的args --

val canonicalized =
  args.foldLeft(false -> List.empty[String]) { (state, arg) =>
    val (afterDashes, result) = state
    if (afterDashes) true -> (arg :: result)  // pass through unchanged
    else {
      if (arg == "==") true -> (arg :: result) // move to afterDash state & pass through
      else {
        if (arg.startsWith("--")) false -> (arg.toLowerCase :: result)
        else false -> (arg :: result) // pass through unchanged
      }
    }
  }
  ._2    // Extract the result
  .reverse // Reverse it back into the original order (if building up a sequence, your first choice should be to build a list in reversed order and reverse at the end)

  OptionsParser.parse(canonicalized, Args())

关于第二个问题,因为Argsis (几乎可以肯定) a case class,它有一个copy方法可以构造一个新对象,该对象具有(很可能,取决于使用情况)其字段的不同值。所以

 args.copy(cust = cust)

创建一个新Args对象,其中:

  • cust对象中字段的值是cust该块中变量的值(这基本上是一个有点聪明的技巧,适用于命名方法参数)
  • 每个其他字段的值都取自args
于 2020-09-28T15:06:21.883 回答