2017-07-03 3 views
2

Je souhaite analyser les options de ligne de commande avec des arguments dans OCaml.OCaml - Analyse des options de ligne de commande avec des arguments utilisant Arg

Le module Arg de la bibliothèque standard semble faire tout ce dont j'ai besoin et il y a quelques tutoriels qui expliquent comment utiliser ce module.

Mon problème est, qu'ils semblent tous partager le même comportement étrange quand l'argument d'une option est manquant. Par exemple, l'exécution du programme de this example avec ./a.out -d produit la sortie suivante:

./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 

je n'étais pas en mesure de savoir pourquoi le message d'erreur/usage est imprimé trois fois. Cela arrive aussi à tous les autres exemples de code que j'ai trouvés en ligne. Est-ce un problème dans le module Arg ou est-il en quelque sorte pas utilisé correctement dans ces exemples?

+0

Quelle version du compilateur utilisez-vous? (J'ai réussi à reproduire sous 4.04.2 dès maintenant) – RichouHunter

+0

L'exécution avec OCaml 4.02.3 ne provoque pas ce comportement. Je vous suggère de vérifier [OCaml bug-tracker] (https://caml.inria.fr/mantis/view_all_bug_page.php) pour voir si ce problème a déjà été signalé. :) – RichouHunter

Répondre

3

J'ai réussi à reproduire le bogue avec OCaml 4.04.2, mais pas avec 4.02.3, donc il semblerait qu'il y ait une sorte de régression. Donc, une chose que vous pourriez faire est de coller à une ancienne version d'OCaml, mais je ne le recommanderais pas. Au lieu de cela, vous pouvez utiliser une bibliothèque standard alternative, telle que Core de Jane Street. Il a un module nommé Command qui vous permet d'écrire des interfaces de ligne de commande exactement comme celle que vous essayez d'exécuter.

Un didacticiel étendu pour ce module est disponible here.

À titre d'exemple, voici la CLI de Rosetta en utilisant Command:

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: était connu Ce bogue et is going to be fixed in OCaml 4.05.

+0

Je ne suis pas très expérimenté avec l'opam, mais il semble que 'opam install core' nécessite de rétrograder le paquet zarith à 1.4.1. Malheureusement, mon projet dépend de zarith 1.5. D'autres paquets de ligne de commande comme 'getopt' ou' getopts' semblent dépendre d'une ancienne version de zarith. Néanmoins, merci pour votre réponse. Je suppose que le fait d'avoir plusieurs versions du même paquet rendrait tout plus compliqué, ce qui signifie que j'attends plutôt OCaml 4.05. au lieu. – tomatenbrei

+0

Juste une idée: avez-vous lancé 'opam update' avant d'essayer d'installer' core'? – RichouHunter

+0

Non, mais 'opam update' n'a malheureusement pas changé la version requise de zarith. – tomatenbrei