> Date: Wed, 19 Jul 2006 15:07:29 +0100
> From: Richard Jones <rich@annexia.org>
> Subject: Re: [Caml-list] global record
> To: Andreas Biegert <andreas.biegert@googlemail.com>
> Cc: caml-list@yquem.inria.fr

>This is a bit ugly, but we use it in our Adwords API toolkit:
>
>-------------------------------------------------- stdargs.mli
>val username : string
>val password : string
>val client : string option
>val token : string
>val update : bool
>val verbose : bool
>val args : string list
>
>-------------------------------------------------- stdargs.ml
>let username = ref ""
>let password = ref ""
>let client = ref ""
>let token = ref ""
>let update = ref false
>let verbose = ref false
>let args = ref []
>
>(* followed by some code which tries to read default values
> * from $HOME/.adwordsapidata -- code omitted
> *)
>
>(* parse the command line parameters *)
>let argspec = [
>  "--username", Arg.Set_string username, "Adwords account username.";
>  "--password", Arg.Set_string password, "Adwords account password.";
>  "--client", Arg.Set_string client, "Adwords account client (optional).";
>  "--token", Arg.Set_string token, "Adwords account token.";
>  "--update", Arg.Set update, "Perform updates.";
>  "--verbose", Arg.Set verbose, "Be verbose.";
>]
>
>let anon_fn str = args := str :: !args
>let usage =
>  Sys.executable_name ^ " [--options]"
>
>let () = Arg.parse argspec anon_fn usage
>
>let username = !username
>let password = !password
>let client = if !client = "" then None else Some !client
>let token = !token
>let update = !update
>let verbose = !verbose
>let args = List.rev !args
>
>---
>
>Then the code just stuff like:
>
>  open Stdargs
>
>  if verbose then printf "this is verbose mode\n"

<gauche_self_promotion>

I was also writing code that looked like that, and I got tired of the duplication, and also the non-locality - each new option requires a modification in several places.  So the pa_arg syntax extension I just announced makes this a lot easier.  Except for the reading of values from the dotfile, all the above code is generated from this declaration (not tested):

open Parseopt

type option myopts = {
username = "" : help = "Adwords account username"; string;
password = "" : help = "Adwords account password";  string;
client: help = "Adwords account client (optional)"; string;
token = "": help = "Adwords account token"; string;
update = false: help = "Perform updates"; action = set; bool;
verbose = false: help = "Be verbose"; action = set; bool;
}
let myopts = {myopts with keyspecs = [Long2]} in (** specify you want field foo => --foo *)

let options, args = parse_argv myopts in

...

if options.verbose then print "this is verbose mode!\n"

...

You also get a detailed usage and help message and a function to convert the returned options to a string, plus further customizability.

http://www.cs.cornell.edu/~ebreck/pa_arg

-E r i c

</gauche_self_promotion>