Ruby methods and ordering of multiple default values

ruby

Solution

Only elegant solution for now is to use hash as parameters list:

def some_method(options = {})
  defaults = {:arg1 => 1, :arg2 => 2, :arg3 => 3}
  options = defaults.merge(options)
  ...
end

and later in code use implicit hash when calling your method:

some_method()
some_method(:arg1 => 2, :arg2 => 3, :arg3 => 4)
some_method(:arg2 => 4)

In Ruby 1.9 you can use new hash keys syntax to get ir more like in Python:

some_method(arg1: 2, arg2: 3, arg3: 4)

If you want simpler syntax and still be able to use positional parameters, then I would suggest to play with something like this:

def some_method(*args)
  defaults = {:arg1 => 1, :arg2 => 2, :arg3 => 3}
  options = args.last.is_a?(::Hash) ? args.pop : {}
  options = defaults.merge(options)

  arg1 = args[0] || options[:arg1]
  arg2 = args[1] || options[:arg2]
  arg3 = args[2] || options[:arg3]
  ...
end

some_method()
some_method(2)
some_method(3,4,5)
some_method(arg2: 5)
some_method(2, arg3: 10)

If you would like to mimic Ruby arguments number check for method, you can add:

fail "Unknown parameter name(s) " + (options.keys - defaults.keys).join(", ") + "." unless options.length == defaults.length

EDIT: I updated my answer with Jonas Elfström's comment

Problem

I seem to not be able to do this (which I used to be able to do in Python). Let me explain .. Suppose I have the following method in Ruby: ``` def someMethod(arg1=1,arg2=2,arg3=3) ... ... ... end ``` Now to call this method I could do ``` someMethod(2,3,4) someMethod(2,3) someMethod(2) ``` and the arguments are taken by their respective order.. but what if I want to give arg2 at some point in my programming and want the default values for arg1 and arg3? I tried writing someMethod(arg2=4) but this doesn't seem to work in Ruby 1.9. What it does is it still thinks that arg1 is 4. In python I could at least get away with this, but in ruby I am not sure. Does anyone have any elegant ideas?

Original source