Sebastian Staudt edited this page Jan 23, 2011 · 8 revisions
Clone this wiki locally

Rubikon's DSL (domain specific language) was created with both, simplicity and power, in mind. This page will teach you how to use it.


The DSL of Rubikon knows three different types of command-line arguments as parsed by the application:

  1. Commands – These contain the logic behind an application. A command would be something like Git's commit or RubyGems' install.
  2. Parameters – These are command-line arguments changing the behavior of the application. Parameters start with either one (for single character parameters) or two dashes (for longer parameter names). There are flags and options:
    • Flags – They don't take any additional arguments and are usually used to enable or disable specific features. For example --amend would be a flag for Git's commit command.
    • Options – Options may take one or more arguments. Some or all of them may be required.
  3. Arguments – These are any other arguments passed to the application by the user and may contain arbitrary data. Arguments may be passed to commands or options. For example HEAD is an argument passed to Git's reset command and a commit message is passed to the -m option of the commit command.


Commands are defined using the following syntax:

command :something do
  # Any code that should be executed for this command inside this block

Additionally you may define a default command that is executed if the user doesn't specify a command.

default do
  # Code that should be executed when no command is supplied


You can define global parameters – usable throughout the application – and local parameters – specific to the command they belong to.

Local, command-specific parameters have to be defined before the command they belong to.

flag :quiet
option :name, 1
command :something do
  # Command code

The second parameter to option indicates the number of arguments this option takes. A positive number indicates the count of required arguments while a negative number indicates the count of required arguments plus an arbitrary number of optional arguments. A argument count of 0 indicates there are no required arguments, but optional arguments are allowed.

The example above could be called like follows: app something --more --name test

Both flags and options may have additional blocks that get executed as soon as the user supplies the corresponding command-line argument.

flag :'dry-run' do
  puts 'Nothing is happening.'


You may even define aliases to other existing commands and parameters like this:

command :s => :something
flag :q => :quiet
option :n => :name

Please note that these aliases may be defined before or after the real definition of the commands and parameters they are aliasing.


Options have to be and commands may be defined so they accept one or more arbitrary arguments that have to be passed by the user. The arguments are passed to the command or option definition as the second parameter.

option :name, 1
command :something, 2 do
  # Command code

That way the option --name of the command something would require one argument and the command itself would require two arguments. A valid call to this command could look like app something --name test left right or equally app something left right --name test. This would use the value test as the argument to the --name option and the values left and right to the command something.

There are several possible ways to define arguments:

  • A positive number to define a exact count of required arguments – e.g. 2 would allow only two arguments.
  • A negative figure to define a number of required arguments but also allow optional arguments – -1 will require one argument but will also allow more than that.
  • A range to define a variable argument count – for example 1..3 would allow one to three arguments.
  • An array of symbols defines an exact count of required named arguments – e.g. :first, :second will allow exactly two arguments where the first one is called first and the next one second.

Options for named arguments

As you can see in the paragraph above, you can create named arguments with symbols. Additionally, you may specify options for each of this arguments when you don't use an array of symbols but a hash with the argument names as keys. An example will show you how to do this:

command :something, :first, :second => :optional, :more => :remainder

This would create a required argument called :first, another optional one called :second and all additional arguments would be put into an array called :more. Both ,:optional and :remainder can be combined when using them in an array: :more => [:optional, :remainder].

Validating argument values

Named arguments may also be specified with one or more so called validators. This may be either one of the predefined regular expressions (:alnum, :float, :letters, :numeric), a string that should be exactly matched or a custom regular expression matching anything you want.

option :count, :number => [:numeric, 'none', /one|two|three/]

You can also combine validators with other options (see above): :number => [:optional, :numeric, 'none', /one|two|three/]

Accessing parameters and arguments in your code

Inside the code block of an option you can easily access its arguments values. In a similar way you can access a command's parameters and arguments inside the code block of the argument. Have a look at the following example to see how:

option :somebody, [:who] do
  # Equivalent ways of accessing the argument's value
  puts args[0]
  puts self[0]
  puts self[:who]
  puts who
command :something, [:what] do
  puts what            # The value of the command's argument
  puts self[:what]     # The value of the command's argument
  puts somebody.given? # true if --somebody was supplied
  puts who             #  The value of --somebody's argument
  puts somebody.who    # The value of --somebody's argument
  puts somebody[0]     # The value of --somebody's argument

These various ways of accessing parameters and arguments are equivalent and therefore interchangeable at will.

Note: Right now it's not possible to access a named argument using e.g. args[:arg_name] due to args being always an array. This will change in the future and Rubikon will provide an intelligent way to access arguments using both numeric and symbolic indices in combination with args. The [] shortcut already works for both.

Note: Additionally it's not possible to access a parameter or argument using the short syntax (e.g. who and somebody above) when it's named like an existing method of Parameter, HasParameter or Command respectively, e.g. name. In that case you have to use a more explicit syntax like self[:name].


You may define code that will be executed at a specific time in the application lifecycle. The following hooks are available:

  • pre_init – Called before the application is initialized
  • post_init – Called after the application has been initialized
  • pre_execute – Called before the execution of a command
  • post_execute – Called after the execution of a command

An example use would be:

pre_execute do

post_execute do

Note: Hook support is preliminary at the moment. This will be extended and configurable in the future.