2017-07-03 152 views
2

我想用OCaml中的参数解析命令行选项。OCaml - 使用参数解析带参数的命令行选项

标准库的模块Arg似乎做我需要的一切,并有一些教程解释如何使用此模块。

我的问题是,当一个选项的参数丢失时,它们似乎都共享相同的奇怪行为。例如,从与this example./a.out -d执行程序产生以下输出:

./a.out: option '-d' needs an argument. 
usage: ./a.out [-b] [-s string] [-d int] 
    -b : set somebool to true 
    -s : what follows -s sets some string 
    -d : some int parameter 
    -help Display this list of options 
    --help Display this list of options 
./a.out: ./a.out: option '-d' needs an argument. 
usage: ./a.out [-b] [-s string] [-d int] 
    -b : set somebool to true 
    -s : what follows -s sets some string 
    -d : some int parameter 
    -help Display this list of options 
    --help Display this list of options 
. 
usage: ./a.out [-b] [-s string] [-d int] 
    -b : set somebool to true 
    -s : what follows -s sets some string 
    -d : some int parameter 
    -help Display this list of options 
    --help Display this list of options 

我无法找出为什么错误/用法消息被打印三次。这也发生在我在网上找到的所有其他代码示例中。这是Arg模块中的问题,还是在这些示例中以某种方式未正确使用?

+0

你使用什么版本的编译器? (我已经设法在4.04.2下现在重现) – RichouHunter

+0

使用OCaml 4.02.3运行不会导致此行为。我建议你检查一下[OCaml bug-tracker](https://caml.inria.fr/mantis/view_all_bug_page.php),看看这个问题是否曾经被报告过。 :) – RichouHunter

回答

3

我已经成功地重现了OCaml 4.04.2的错误,但没有使用4.02.3,所以看起来似乎有某种回归正在进行。

所以,你可以做的一件事是坚持OCaml的旧版本,但我不会建议。您可以使用替代标准库,例如Jane Street的Core。它有一个名为Command的模块,它允许您编写与您尝试运行的命令行界面相似的命令行界面。

该模块的详细教程可用here

作为一个例子,这里是使用从Command罗塞塔的CLI:

open Core 

let spec = 
    let open Command.Spec in 
    empty 
    +> flag "-b" (no_arg) ~doc:"Sets some flag" 
    +> flag "-s" (optional_with_default "" string) ~doc:"STRING Some string parameter" 
    +> flag "-d" (optional_with_default 0 int) ~doc:"INTEGER Some int parameter" 

let command = 
    Command.basic 
    ~summary:"My awesome CLI" 
    spec 
    (fun some_flag some_string some_int() -> 
     printf " %b '%s' %d\n" some_flag some_string some_int 
    ) 

let() = 
    Command.run command 

EDIT:此错误已知的,并且is going to be fixed in OCaml 4.05

+0

我对opam并不是很有经验,但似乎'opam install core'需要将包zarith降级到1.4.1。不幸的是,我的项目取决于zarith 1.5。像getopt或getopts这样的其他命令行包似乎也取决于旧版本的zarith。 不过谢谢你的回应。我想有多个版本的同一个软件包会使一切变得更加复杂,这意味着我宁愿等待OCaml 4.05。代替。 – tomatenbrei

+0

只是想一想:在尝试安装core之前是否运行过“opam update”? – RichouHunter

+0

不,但'opam update'遗憾地没有改变zarith的所需版本。 – tomatenbrei