ruby optparse

Cómo analizar un argumento sin un nombre con Ruby optparse



(5)

Necesito analizar una línea de comando como

script.rb <mandatory filename> [options]

con optparse .

Claro que puedo escribir un código personalizado para manejar el nombre de archivo, luego pasar ARGV a optparse, pero ¿tal vez hay una forma más sencilla de hacerlo?

EDITAR: hay otra forma pirata de analizar dicha línea de comando, y es pasar [''--mandatory-filename''] + ARGV a optparse, luego manejar la opción --mandatory-filename .


Aunque no se aplica a todas las situaciones, a menudo es bueno poder procesar varios archivos en una sola línea de comando, como:

script.rb [options] file1 file2 ...

file1 es obligatorio, pero file2 y más allá son opcionales.

La mejor manera que conozco para hacer esto sigue esta convención:

options = {} optparse = OptionParser.new do |opts| opts.banner = "Usage: script.rb [options] file1 file2 ..." opts.on(''-a'', ''--an-option ARG'', ''Set some option'') do |arg| options[:a] = arg end ... end optparse.parse! # Check required conditions if ARGV.empty? puts optparse exit(-1) end

Si no se proporcionan los archivos, se mostrará un mensaje de ayuda con el banner de uso y una descripción de las opciones. Si los archivos están presentes, serán lo único que quedará en ARGV.


No estoy seguro de si se agregó recientemente, pero ninguna de las respuestas anteriores menciona que optparse.parse devolverá el valor ARGV después de eliminar las opciones analizadas.

Si haces esto:

rest = optparse.parse!

Obtendrá una matriz con el / los archivo (s) dado (junto con las opciones desconocidas). De esta manera, no tiene que preocuparse si las opciones vienen antes o después del archivo.


Optparse solo hace argumentos con parámetros, AFAIK. La forma "correcta" de manejar su nombre de archivo es lidiar con él fuera de optparse. Publiqué un código de ejemplo para esto en respuesta a this pregunta.

Por cierto, eso es una línea de comando bastante inusual. Si es solo para ti, está bien, pero es probable que otros lo encuentren más bien contraintuitivo. Sería más normal tener: script.rb [options] <filename> ...


Primer parse! con optparse, luego escanee el ARGV y aumente si ARGV está vacío. Al igual que:

op.parse! filename = ARGV.pop raise "Need to specify a file to process" unless filename

OptionParser no procesará el nombre de archivo obligatorio y se lo dejará en ARGV; si no está allí, simplemente créelo manualmente.


Solo para dar seguimiento a lo que Julik y Shadowfirebird dijeron: Cuando analice con OptionParser tenga en cuenta que parse! y parse tienen diferentes funcionalidades. El primero eliminará todos los argumentos que entienda de la matriz pasada, donde el último los dejará como están. Esto cambia sus condiciones para determinar si el argumento requerido está presente.