我正在尝试使用Arg.parse
OCaml函数来读取命令行选项和参数,包括未指定以-
开头的参数。根据手册:
要让用户能够指定以 - 开头的匿名参数,请在
("-", String anon_fun, doc)
中包含例如speclist
。
所以我希望这个例子有效:
let other_option x = Format.printf "Other option: %s@." x
let other_argument x = Format.printf "Other argument: %s@." x
let arg_speclist =[
("-a", Arg.Unit (fun () -> Format.printf "Known option: -a@."), "option a");
("-", Arg.String other_option, "any option")
]
let () = Arg.parse arg_speclist other_argument "Usage:"
使用指定的-a
选项和其他参数,它正在运行:
$ ocaml test.ml arg1 -a arg2
Other argument: arg1
Known option: -a
Other argument: arg2
但尝试使用以-
开头的内容时不是这样:
$ ocaml test.ml -x test.ml: unknown option '-x'. Usage: -a option a - any option -help Display this list of options --help Display this list of options
我希望调用other_option
函数。
我做错了什么?
答案 0 :(得分:4)
使用("-", String anon_fun, doc)
并不允许您按照自己的想法行事,它允许您以这种方式输入选项:
ocaml test.ml - -x
基本上,它使"-"
成为"逃避"将下一个传递给anon_fun的选项。
您想要的确切行为无法通过Arg
轻松完成(这绝不是一个详尽的复杂参数解析器AFAIK)。
作为一种可能的解决方法,您可以先手动浏览argv(不要忘记阅读0
)并动态地向您的规范列表中添加选项:
let speclist = [ ("-option", Arg.String print_endline, "handled option") ]
let speclist =
let r = ref speclist in
for i = 1 to pred (Array.length Sys.argv) do
let s = Sys.argv.(i) in
if s.[0] = '-' && not List.exists (fun (s',_,_) -> s = s') !r
then r := (s, Arg.Unit (fun () -> anon_fun s), "any_option") :: !r
done;
!r
另一种选择是从Arg
获取代码并根据您的模型进行修改,或使用其他更强大的工具。也许Cmdliner
是您正在寻找的东西(我从未使用过它,所以我不知道它是否有效)。