OCaml文盲需要记录操作协助

时间:2014-06-27 18:25:34

标签: ocaml command-line-arguments record

这有点令人尴尬,但我已经看过一个OCaml程序,我知道我想做什么,但我找不到文档来帮助我用正确的语法写出我想要的东西,因为我已经从来没有使用过这门语言。

我对程序做了很多工作,这恰好是我需要做的最后一次更改,我无法解决这个问题!

有一个名为caps_default的排序记录(使用的语法让我失望):

let caps_default =
    {
        browserName = Firefox ;
        version = "" ;
        platform = ANY ;
        username = "" ;
        accessKey = "" ;
        javascriptEnabled = true
    }
;;

然后定义这些变量以接收命令行参数:

exception Incorrect_cmdline of string option
;;

let browser_name   = ref ""
and hub_url_opt    = ref ""
and target_url_opt = ref ""
and xml_out_string = ref ""
and user_name      = ref ""
and access_key     = ref ""
;;

我添加了两个名为' username'和' accessKey'我想将它们添加到"大写"记录的东西。

继续,这里解析命令行参数:

let (target_url, hub_url, caps, xml_out) =
    try
        parse_cmdline
            [
                ( noshort , "browser-name" , None, (atmost_once browser_name   (Incorrect_cmdline (Some "browser-name"))) ) ;
                ( noshort , "hub-url"      , None, (atmost_once hub_url_opt    (Incorrect_cmdline (Some "hub-url"))) ) ;
                ( noshort , "target-url"   , None, (atmost_once target_url_opt (Incorrect_cmdline (Some "target-url"))) ) ;
                ( noshort , "xml-output"   , None, (atmost_once xml_out_string (Incorrect_cmdline (Some "xml-output"))) ) ;
                ( noshort , "username"     , None, (atmost_once user_name      (Incorrect_cmdline (Some "username"))) ) ;
                ( noshort , "accessKey"    , None, (atmost_once access_key     (Incorrect_cmdline (Some "accessKey"))) ) ;
                ( noshort , "help"         , Some (fun s -> raise (Incorrect_cmdline None)) , None );
            ]
            ( fun x -> raise (Incorrect_cmdline None)) ;
        ignore (List.map
                (fun s -> if BatString.is_empty !s then raise (Incorrect_cmdline None) else () )
                [ browser_name ; hub_url_opt ; target_url_opt ] );
        let target_url =
            try
            Neturl.parse_url !target_url_opt
            with
            Neturl.Malformed_URL ->
            raise (Incorrect_cmdline (Some ("Invalid target url: " ^ !target_url_opt)))
        and hub_url =
            try
            Neturl.parse_url !hub_url_opt
            with
            Neturl.Malformed_URL ->
            raise (Incorrect_cmdline (Some ("Invalid hub url: " ^ !hub_url_opt)))
        and xml_out =
            if BatString.is_empty !xml_out_string
            then fun s -> ignore s
            else
            let chan = open_out !xml_out_string in
            (fun xml ->
            output_string chan (Xml.to_string xml) ;
            close_out chan )
        (* Continued below *)

我希望将分配给变量usernameaccessKey的新命令行参数选项user_nameaccess_key传递给{{1在下面的let assignments中定义的记录:

caps

尝试我可以将原作者的--browser-name开关注释掉,并通过放置由花括号包围的庄严线来指定单个值:

        (* Continued from above *)
        and caps =
            { caps_default with username = !user_name }   (* My addition *)
            { caps_default with accessKey = !access_key } (* My addition *)
            match !browser_name with   (* This switch is original and worked *)
            | "firefox"   -> { caps_default with browserName = Firefox }
            | "chrome"    -> { caps_default with browserName = Chrome }
            | "html_unit" -> { caps_default with browserName = HtmlUnit }
            | "ie"        -> { caps_default with browserName = InternetExplorer }
            | "iphone"    -> { caps_default with browserName = IPhone }
            |  _        -> raise (Incorrect_cmdline (Some ("Invalid browser name: " ^ !browser_name)))
        in
        (target_url, hub_url, caps, xml_out)
    with
        Incorrect_cmdline arg ->
            (match arg with | None -> () | Some msg -> print_endline msg) ;
            print_synopsis () ;
            exit 48
;; (* End of relevant code *)

and caps=
    { caps_default with browserName = Chrome } (* Hard-coding a Chrome choice *)

and caps=
    { caps_default with username = !user_name } (* Sharing only --username *)

有人能指出我正确的方向吗?我想保留原作者写的开关,但也将and caps= { caps_default with accessKey = !access_key } (* Sharing only --accessKey *) username字符串传送到accessKey记录。我可以稍后更改caps对象吗?我可以事先修改caps,然后将其复制到default_caps吗?

此代码每次执行只运行一次,因此修改caps对象绝对不会引起关注,即使它不是非常犹豫不决。

感谢您的帮助!

更新

非常感谢斯科菲尔德先生迄今提供的帮助。奇怪的是,我现在遇到了一个稍微不同的错误,抱怨我只能假设类型不匹配。以下是错误的内容:

default_caps

第110行

File "tester.ml", line 110, characters 40-47:
Error: This expression has type Selenium.Json_client.capabilities
       but an expression was expected of type Selenium.Json_client.browser

在斯科菲尔德先生的代码片段中,40-47为{ caps_default with browserName = browser;

browser类型default_caps的定义是这样的:

capabilities

类似地,类型type capabilities = { browserName : browser ; version : string ; platform : platform ; javascriptEnabled : bool ; username : string ; accessKey : string ; }

browser

如果重要的话,mli(接口,正确?)定义是相同的。

更新第2部分

仅需要进行小修正以简化代码:

type browser =
  Chrome | Firefox | HtmlUnit | InternetExplorer | IPhone

到此:

match !browser_name with
| "firefox"   -> { caps_default with browserName = Firefox }
| "chrome"    -> { caps_default with browserName = Chrome }
| "html_unit" -> { caps_default with browserName = HtmlUnit }
| "ie"        -> { caps_default with browserName = InternetExplorer }
| "iphone"    -> { caps_default with browserName = IPhone }
|  _        -> raise (Incorrect_cmdline (Some ("Invalid browser name: " ^ !browser_name)))

继续之前:

match !browser_name with
| "firefox"   -> Firefox
| "chrome"    -> Chrome
| "html_unit" -> HtmlUnit
| "ie"        -> InternetExplorer
| "iphone"    -> IPhone
|  _        -> raise (Incorrect_cmdline (Some ("Invalid browser name: " ^ !browser_name)))

1 个答案:

答案 0 :(得分:1)

你可能需要学习一些比你想要的更多的OCaml: - )

名为caps_default的东西是一条记录,即它有一个记录类型。您将不得不找到此记录类型的定义并向其添加新功能。

<强>更新

好的,你已经修好了记录类型。这是一些代码

    and caps =
        let browser = 
            match !browser_name with
            | "firefox"   ->  Firefox
            | "chrome"    ->  Chrome
            | "html_unit" ->  HtmlUnit
            | "ie"        ->  InternetExplorer
            | "iphone"    ->  IPhone
            |  _        ->
                raise (Incorrect_cmdline
                   (Some ("Invalid browser name: " ^ !browser_name)))
        in
        { caps_default with browserName = browser;
                            username = !user_name;
                            accessKey = !access_key;
        }
    in
    (target_url, hub_url, caps, xml_out)

(不用说,这是未经测试的代码。)

更新2

user_name的固定拼写,谢谢。)