2014-09-01 1 views
1

J'ai un script d'analyse syntaxique de cli rubis et il semble qu'il y ait une sorte de comportement regex pour les options d'analyse syntaxique:comportement optparse Ruby WRT InvalidOption vs exceptions MissingArgument

op = OptionParser.new do |x| 

     x.on("--output-config PATH", "The filesystem location for the output config file") do |output_config| 
     options[:output_config] = output_config 
     end 

     x.on("-j", "--json", "If this is set, then json is output instead of tabular form") do 
     options[:disp_json] = true 
     end 

     x.on("-h", "--help", "Show this message") do 
     puts op 
     exit 0 
     end 

     x.on("-v", "--version", "Show version") do 
     puts "version #{VERSION_NUMBER}" 
     exit 0 
     end 
    end 


    # do input validation and check leftovers for proper commands 
    begin 
    # parse options, parse! removes elements from ARGV so leftovers are positional arg(s) 
    op.parse!(ARGV) 
    options[:config_file] = ARGV[0] if ARGV[0] 

    rescue OptionParser::InvalidOption, OptionParser::MissingArgument 
    puts "############### #{$!.to_s} ###############" 
    puts "" 
    puts op 
    exit 1 
    end 

Alors si je l'appelle comme tel:

script -a 

Il produit les éléments suivants (comportement attendu)

############### invalid option: -a ############### 

Ou

script --output-config 

Il produit les éléments suivants (comportement attendu)

############### missing argument: --output-config ############### 

C'est donc là que ça devient bizarre:

script --output 

Il produit les éléments suivants (pas comportement attendu)

############### missing argument: --output ############### 

Ou

script --ou 

Il produit les éléments suivants (pas comportement attendu)

############### missing argument: --ou ############### 

Au fond de tout ce que vous passez correspondant regex "sortie-config" est passé au bloc pour

x.on("--output-config PATH".... 

Quelle est la cause du comportement MissingArgument vs InvalidOption que je vois. Est-ce que j'utilise optparse faux ou est-ce un bug dans la bibliothèque?

####### EDIT

Si j'ajoute une autre x.on:

x.on("--out PATH", "The filesystem location for the output config file") do |output_config| 
    options[:output_config2] = output_config 
end 

Et passe soit -o (un tiret, par exemple une forme courte) ou --o (deux tirets), il ne lance pas d'exception (je suis spécifiquement en train de sauver OptionParser :: AmbiguousOption à la manipulation n'est pas exécutée). Au lieu de cela, exécute la correspondance la plus courte, qui est --out. Si je passe --outp, alors le plus long est exécuté. Cela me semble flou.

####### EDIT 2
> ./my_app --output-c 
############### missing argument: --output-c 

L'exception MissingArgument affiche uniquement le drapeau comme passé, non pas comme 'destination'. Il sait clairement qu'il correspond à '--output-config' donc j'aimerais pouvoir le savoir pour que mon message d'erreur à l'utilisateur soit clair et explicite. Existe-t-il un moyen de déterminer à quoi correspond optparser au moment où l'exception MissingArgument a été déclenchée?

Répondre

1

Ceci est un comportement standard avec des options longues. J'ai de la difficulté à trouver de la documentation à l'appui, mais j'utilise cette fonctionnalité de longues options tant que j'utilise de longues options (c'est-à-dire depuis longtemps).

Vous pouvez le voir facilement avec la version GNU de ls (1):

$ ls --h 
ls: option '--h' is ambiguous 
Try `ls --help' for more information. 

$ ls --he 
Usage: ls [OPTION]... [FILE]... 
List information about the FILEs (the current directory by default). 
Sort entries alphabetically if none of -cftuvSUX nor --sort. 
... 

$ ls --help 
Usage: ls [OPTION]... [FILE]... 
List information about the FILEs (the current directory by default). 
Sort entries alphabetically if none of -cftuvSUX nor --sort. 
... 

Il y a plusieurs options qui commencent par --h si --h est une erreur d'options, il n'y a qu'une seule option qui commence avec --he alors --he est la même que --help.

Si vous ajoutez une option --output-pancakes, alors vous devriez obtenir une plainte au sujet d'ambiguïté si vous dites --output mais --output-c et --output-p fonctionnera.

Vous n'utilisez pas la bibliothèque de manière incorrecte. Ce n'est pas non plus un bug. C'est une caractéristique.

+0

Intéressant, consultez mon edit ci-dessus ^^^. – jshort

+0

Mais '--out' est différent,' --out' est une correspondance exacte pour une option, donc il n'y a pas d'ambiguïté. Si j'ajoute une option '--output-pancakes PATH' et que j'utilise' --output', j'obtiens un 'OptionParser :: AmbiguousOption'. L'analyse est intentionnellement floue. –

+0

Ok vient de confirmer ce que vous avez dit être vrai. Qu'en est-il du fait qu'il prend automatiquement la forme abrégée pour la forme longue? Aussi, si c'est juste un fait qu'optparse essaye automatiquement de faire correspondre l'option (ie --ou => --out) alors quand attraper une exception MissingArgument, il serait bon de savoir quelle option explicitement listée l'argument est manquant l'utilisateur peut voir le menu d'aide et savoir quelle option avait un argument requis qu'ils ont arrêté. – jshort