Este grupo de expertos pasados ciertos días de trabajo y de recopilar de información, obtuvimos la solución, queremos que te sea útil en tu trabajo.
Solución:
El OptionParser incorporado de Ruby hace esto muy bien. Combínalo con OpenStruct y estarás en casa gratis:
require 'optparse'
options =
OptionParser.new do |opt|
opt.on('--first_name FIRSTNAME') o
opt.on('--last_name LASTNAME') options[:last_name] = o
end.parse!
puts options
options
contendrá los parámetros y valores como un hash.
Guardar y ejecutar eso en la línea de comando sin parámetros da como resultado:
$ ruby test.rb
Ejecutándolo con parámetros:
$ ruby test.rb --first_name=foo --last_name=bar
:first_name=>"foo", :last_name=>"bar"
Ese ejemplo está usando un Hash para contener las opciones, pero puede usar un OpenStruct que dará como resultado un uso como su solicitud:
require 'optparse'
require 'ostruct'
options = OpenStruct.new
OptionParser.new do |opt|
opt.on('-f', '--first_name FIRSTNAME', 'The first name')
opt.on('-l', '--last_name LASTNAME', 'The last name') o
end.parse!
puts options.first_name + ' ' + options.last_name
$ ruby test.rb --first_name=foo --last_name=bar
foo bar
Incluso crea automáticamente su -h
o --help
opción:
$ ruby test.rb -h
Usage: test [options]
--first_name FIRSTNAME
--last_name LASTNAME
También puedes usar banderas cortas:
require 'optparse'
options =
OptionParser.new do |opt|
opt.on('-f', '--first_name FIRSTNAME') options[:first_name] = o
opt.on('-l', '--last_name LASTNAME')
end.parse!
puts options
Corriendo eso a través de sus pasos:
$ ruby test.rb -h
Usage: test [options]
-f, --first_name FIRSTNAME
-l, --last_name LASTNAME
$ ruby test.rb -f foo --l bar
:first_name=>"foo", :last_name=>"bar"
También es fácil agregar explicaciones en línea para las opciones:
OptionParser.new do |opt|
opt.on('-f', '--first_name FIRSTNAME', 'The first name')
opt.on('-l', '--last_name LASTNAME', 'The last name') options[:last_name] = o
end.parse!
y:
$ ruby test.rb -h
Usage: test [options]
-f, --first_name FIRSTNAME The first name
-l, --last_name LASTNAME The last name
OptionParser también admite la conversión del parámetro a un tipo, como un número entero o una matriz. Consulte la documentación para obtener más ejemplos e información.
También debe mirar la lista de preguntas relacionadas a la derecha:
- “Análisis de opciones de línea de comandos realmente barato en Ruby”
- “Pasar variables al script de Ruby a través de la línea de comandos”
Basado en la respuesta de @MartinCortez, aquí hay una breve excepción que hace un hash de keypares /valor, donde los valores se deben unir con un =
firmar. También admite argumentos de bandera sin valores:
args = Hash[ ARGV.join(' ').scan(/--?([^=s]+)(?:=(S+))?/) ]
…o alternativamente…
args = Hash[ ARGV.flat_maps ]
llamado con -x=foo -h --jim=jam
vuelve "x"=>"foo", "h"=>nil, "jim"=>"jam"
para que puedas hacer cosas como:
puts args['jim'] if args.key?('h')
#=> jam
Si bien hay varias bibliotecas para manejar esto, incluidas GetoptLong
incluido con Ruby: personalmente prefiero rodar el mío. Este es el patrón que uso, lo que lo hace razonablemente genérico, no está vinculado a un formato de uso específico y es lo suficientemente flexible como para permitir banderas, opciones y argumentos necesarios entremezclados en varios órdenes:
USAGE = <'default', :writer=>'chm' # Setting default values
UNFLAGGED_ARGS = [ :directory ] # Bare arguments (no flag)
next_arg = UNFLAGGED_ARGS.first
ARGV.each do |arg|
case arg
when '-h','--help' then ARGS[:help] = true
when 'create' then ARGS[:create] = true
when '-f','--force' then ARGS[:force] = true
when '-n','--nopreview' then ARGS[:nopreview] = true
when '-v','--version' then ARGS[:version] = true
when '-s','--shell' then next_arg = :shell
when '-w','--writer' then next_arg = :writer
when '-o','--output' then next_arg = :output
when '-l','--logfile' then next_arg = :logfile
else
if next_arg
ARGS[next_arg] = arg
UNFLAGGED_ARGS.delete( next_arg )
end
next_arg = UNFLAGGED_ARGS.first
end
end
puts "DocuBot v#DocuBot::VERSION" if ARGS[:version]
if ARGS[:help] or !ARGS[:directory]
puts USAGE unless ARGS[:version]
puts HELP if ARGS[:help]
exit
end
if ARGS[:logfile]
$stdout.reopen( ARGS[:logfile], "w" )
$stdout.sync = true
$stderr.reopen( $stdout )
end
# etc.
Yo personalmente uso Docopt. Esto es mucho más claro, fácil de mantener y fácil de leer.
Eche un vistazo a la documentación de la implementación de Ruby para ver ejemplos. El uso es realmente sencillo.
gem install docopt
código rubí:
doc = < --last_name=
DOCOPT
begin
args = Docopt::docopt(doc)
rescue Docopt::Exit => e
puts e.message
exit
end
print "Hello #args['--first_name'] #args['--last_name']"
Entonces llamando:
$ ./says_hello.rb --first_name=Homer --last_name=Simpsons
Hello Homer Simpsons
Y sin argumentos:
$ ./says_hello.rb
Usage:
says_hello.rb --first_name= --last_name=