I want to call a Ruby script from the command line, and pass in parameters that are key/value pairs.
Command line call:
$ ruby my_script.rb --first_name=donald --last_name=knuth
my_script.rb:
puts args.first_name + args.last_name
What is the standard Ruby way to do this? In other languages I usually have to use an option parser. In Ruby I saw we have ARGF.read
, but that does not seem to work key/value pairs like in this example.
OptionParser looks promising, but I can't tell if it actually supports this case.
Here is a slight modification to @Phrogz excellent answer: this mod will allow you to pass a string with spaces in it.
In a command line pass the string like this:
Or from another ruby script like this:
Results:
Ruby's built-in OptionParser does this nicely. Combine it with OpenStruct and you're home free:
options
will contain the parameters and values as a hash.Saving and running that at the command line with no parameters results in:
Running it with parameters:
That example is using a Hash to contain the options, but you can use an OpenStruct which will result in usage like your request:
It even automatically creates your
-h
or--help
option:You can use short flags too:
Running that through its paces:
It's easy to add inline explanations for the options too:
and:
OptionParser also supports converting the parameter to a type, such as an Integer or an Array. Refer to the documentation for more examples and information.
You should also look at the related questions list to the right:
A bit of standard Ruby Regexp in
myscript.rb
:And on the command line:
$ ruby script.rb --first_name=donald --last_name=knuth
Produces:
$ donald knuth
An improved version that handles arguments that are not options, arguments with a parameter, and
-a
as well as--a
.I personnaly use Docopt. This is much more clear, maintainable and esay-reading.
Have a look to online Ruby implementation doc for examples. Usage is really straightforward.
Ruby code:
Then calling:
And without arguments :
Based on the answer by @MartinCortez here's a short one-off that makes a hash of key/value pairs, where the values must be joined with an
=
sign. It also supports flag arguments without values:…or alternatively…
Called with
-x=foo -h --jim=jam
it returns{"x"=>"foo", "h"=>nil, "jim"=>"jam"}
so you can do things like:While there are multiple libraries to handle this—including
GetoptLong
included with Ruby—I personally prefer to roll my own. Here's the pattern I use, which makes it reasonably generic, not tied to a specific usage format, and flexible enough to allow intermixed flags, options, and required arguments in various orders: