测试是否在nim中设置了docopt命令行选项

时间:2018-01-17 14:17:07

标签: command-line-arguments nim

我试图编写一个可以从标准输入或作为命令行选项提供的文件中读取的nim程序。我使用docopt来解析命令行。

import docopt

const doc = """
This program takes input from a file or from stdin.

Usage:
  testinput [-i <filename> | --input <filename>]

-h --help              Show this help message and exit.
-i --input <filename>  File to use as input.
"""

when isMainModule:
  let args = docopt(doc)
  var inFilename: string
  for opt, val in args.pairs():
    case opt
    of "-i", "--input":
      inFilename = $args[opt]
    else:
      echo "Unknown option" & opt
      quit(QuitFailure)
  let inputSource =
    if inFilename.isNil:
      stdin
    else:
      echo "We have inFilename: " & inFilename
      open(inFilename)

该程序编译。

当我在命令行上给它一个文件时,它不会崩溃:

$ ./testinput -i testinput.nim
We have inFilename: testinput.nim

但是如果我试图从它的stdin中提取它,我会得到一个IOError:

$ ./testinput < testinput.nim
We have inFilename: nil
testinput.nim(28)        testinput
system.nim(2833)         sysFatal
Error: unhandled exception: cannot open: nil [IOError]

为什么inFilename.isNil是假的,但else分支的执行告诉我inFilename&#34;是&#34; nil

有没有一种正确而优雅的方法来使用docopt?

2 个答案:

答案 0 :(得分:1)

我不熟悉docopt,但它似乎为文档中的每个选项创建了一个条目,而不是为用户指定的选项创建条目,因此您的代码已获得args == {"--input": nil}并且字符串化nil

以下内容将正常运行:

import docopt

const doc = """
This program takes input from a file or from stdin.

Usage:
  testinput [-i <filename> | --input <filename>]

-h --help              Show this help message and exit.
-i --input <filename>  File to use as input.
"""

when isMainModule:
  let args = docopt(doc)
  var inFilename: string
  if args["--input"]:
    inFilename = $args["--input"]
  if not inFilename.isNil:
    echo "We have inFilename: " & inFilename
  let inputSource =
    if inFilename.isNil:
      stdin
    else:
      open(inFilename)

另请注意,您不必检查"-i"选项,因为docopt知道它是"--input"的别名。

答案 1 :(得分:0)

不是将选项的值转换为$的字符串,而是将其保留为Value,这是docopt返回的类型。

根据documentation

  

vkNone(无价值)

     

当存在尚未设置且没有默认值的选项时,会出现此类值。转换toBool

时为false

显然可以在布尔表达式中使用选项的值,它似乎自动解释为bool

import docopt

const doc = """
This program takes input from a file or from stdin.

Usage:
  testinput [-i <filename> | --input <filename>]

-h --help              Show this help message and exit.
-i --input <filename>  File to use as input.
"""

when isMainModule:
  let args = docopt(doc)
  var inFilename: Value
  for opt, val in args.pairs():
    case opt
    of "-i", "--input":
      inFilename = val
    else:
      echo "Unknown option" & opt
      quit(QuitFailure)
  let inputSource =
    if not bool(inFilename):
      stdin
    else:
      echo "We have inFilename: " & $inFilename
      open($inFilename)

this other anwser中给出了此行为的另一种用法,并避免设置变量,因此保留变量nil