From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id 52FA0BB83 for ; Wed, 19 Jul 2006 19:14:24 +0200 (CEST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.6/8.13.6) with ESMTP id k6JHENnn019766 for ; Wed, 19 Jul 2006 19:14:23 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id TAA17147 for ; Wed, 19 Jul 2006 19:14:23 +0200 (MET DST) Received: from exchfe2.cs.cornell.edu (exchfenlb-2.cs.cornell.edu [128.84.97.34]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id k6JHELbX021772 for ; Wed, 19 Jul 2006 19:14:22 +0200 Received: from EXCHANGE2.cs.cornell.edu ([128.84.96.42]) by exchfe2.cs.cornell.edu with Microsoft SMTPSVC(6.0.3790.1830); Wed, 19 Jul 2006 13:14:19 -0400 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C6AB56.C4A9C059" X-MimeOLE: Produced By Microsoft Exchange V6.5 Subject: Re: [Caml-list] global record Date: Wed, 19 Jul 2006 13:14:18 -0400 Message-ID: Thread-Topic: [Caml-list] global record Thread-Index: AcarVsSdhwBkOWrvQLi2pQFed+t43Q== From: "Eric Breck" To: X-OriginalArrivalTime: 19 Jul 2006 17:14:19.0602 (UTC) FILETIME=[C5854320:01C6AB56] X-j-chkmail-Score: MSGID : 44BE686F.000 on nez-perce : j-chkmail score : XX : 5/20 0 X-j-chkmail-Score: MSGID : 44BE686D.000 on concorde : j-chkmail score : XX : 5/20 0 X-Miltered: at nez-perce with ID 44BE686F.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 44BE686D.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; api:01 mli:01 val:01 val:01 bool:01 verbose:01 bool:01 verbose:01 omitted:01 printf:01 syntax:01 foo:01 argv:01 api:01 mli:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=HTML_30_40,HTML_MESSAGE autolearn=disabled version=3.0.3 This is a multi-part message in MIME format. ------_=_NextPart_001_01C6AB56.C4A9C059 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable > Date: Wed, 19 Jul 2006 15:07:29 +0100 > From: Richard Jones > Subject: Re: [Caml-list] global record > To: Andreas Biegert > 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 =3D ref "" >let password =3D ref "" >let client =3D ref "" >let token =3D ref "" >let update =3D ref false >let verbose =3D ref false >let args =3D ref [] > >(* followed by some code which tries to read default values > * from $HOME/.adwordsapidata -- code omitted > *) > >(* parse the command line parameters *) >let argspec =3D [ > "--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 =3D args :=3D str :: !args >let usage =3D > Sys.executable_name ^ " [--options]" > >let () =3D Arg.parse argspec anon_fn usage > >let username =3D !username >let password =3D !password >let client =3D if !client =3D "" then None else Some !client >let token =3D !token >let update =3D !update >let verbose =3D !verbose >let args =3D List.rev !args > >--- > >Then the code just stuff like: > > open Stdargs > > if verbose then printf "this is verbose mode\n" 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 =3D { username =3D "" : help =3D "Adwords account username"; string; password =3D "" : help =3D "Adwords account password"; string; client: help =3D "Adwords account client (optional)"; string; token =3D "": help =3D "Adwords account token"; string; update =3D false: help =3D "Perform updates"; action =3D set; bool; verbose =3D false: help =3D "Be verbose"; action =3D set; bool; } let myopts =3D {myopts with keyspecs =3D [Long2]} in (** specify you = want field foo =3D> --foo *) let options, args =3D 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 ------_=_NextPart_001_01C6AB56.C4A9C059 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Re: [Caml-list] global record

> 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 =3D ref ""
>let password =3D ref ""
>let client =3D ref ""
>let token =3D ref ""
>let update =3D ref false
>let verbose =3D ref false
>let args =3D ref []
>
>(* followed by some code which tries to read default values
> * from $HOME/.adwordsapidata -- code omitted
> *)
>
>(* parse the command line parameters *)
>let argspec =3D [
>  "--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 =3D args :=3D str :: !args
>let usage =3D
>  Sys.executable_name ^ " [--options]"
>
>let () =3D Arg.parse argspec anon_fn usage
>
>let username =3D !username
>let password =3D !password
>let client =3D if !client =3D "" then None else Some = !client
>let token =3D !token
>let update =3D !update
>let verbose =3D !verbose
>let args =3D 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 =3D {
username =3D "" : help =3D "Adwords account = username"; string;
password =3D "" : help =3D "Adwords account = password";  string;
client: help =3D "Adwords account client (optional)"; = string;
token =3D "": help =3D "Adwords account token"; = string;
update =3D false: help =3D "Perform updates"; action =3D set; = bool;
verbose =3D false: help =3D "Be verbose"; action =3D set; = bool;
}
let myopts =3D {myopts with keyspecs =3D [Long2]} in (** specify you = want field foo =3D> --foo *)

let options, args =3D 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.e= du/~ebreck/pa_arg

-E r i c

</gauche_self_promotion>

------_=_NextPart_001_01C6AB56.C4A9C059--