dev.Monsterzen.com

Default values and hash arguments with Ruby

09 November 2012

A common and idiomatic solution to the lack of keyword arguments in Ruby methods is the use of hashes. This pattern is used a lot inside Rails and other frameworks.

def search(type, options = {})
  # ...
end

search :people, age: 40, country: 'spain'

But how can we add default values to the options hash argument?. Rails included a useful method in the Hash class called reverse_merge! that we will use to add default values to our options hash argument. Assuming that we need the next following default values: age: 20, country: 'france' the search method will be as follow:

# With Rails (using reverse_merge!)
def search(type, options = {})
  options.reverse_merge! age: 20, country: 'france'
  # ...
end

If you are not using Rails you will not have reverse_merge! included in Hash class so you will need to use other solution, in this case we will use the merge method with the default hash to not losing the possible values indicated in the options argument:

# Without Rails (using merge)
def search(type, options = {})
  options = { age: 20, country: 'france' }.merge(options)
  # ...
end

The approach to the problem using reverse_merge! method is by far more readable and elegant that the version using merge. Perhaps would be a good idea to add this method to the Ruby Core Hash class. Anyway Ruby 2.0 will include keyword arguments and all of this will be unnecessary (or different).