Sergio and the sigil

Playing with Ruby 1.9 - named parameters (sort of)

Posted by Sergio on 2008-12-31

I just installed Ruby 1.9.1 RC1 alongside my stable 1.8.6 installation. I'm planning to experiment with the changes and new language features for both using them in new code and upgrade old code (or at least protect old code from potential breaking changes.)

In light of the upcoming changes in C# 4, more specifically the addition of named and optional parameters, one of the new Ruby 1.9 features called my attention immediately.

Ruby, even 1.9, doesn't support named parameters in method calls. Instead, a common pattern is to provide a Hash parameter and call it something like options. Any optional argument is passed as an item of this hash, normally using a Symbol for the key. It helps that Ruby has special support for hash arguments, making the call look much cleaner:

def my_method(arg1, arg2, options)
  opt1 = options[:option1] || "default value for opt1"
  opt2 = options[:option2] || "default value for opt2"
  # ... etc ...
end

#calling the method:
my_method(val1, val2, { :option2 => "opt val 2", :something => "whatever"})
# simplified syntax
my_method(val1, val2, :option2 => "opt val 2", :something => "whatever")

In a way this is the poor man's version of named parameters, but it seems to do the job.

This is a very popular Ruby idiom (you can see that a lot in JavaScript as well,) so truly popular that the syntax was further simplified in 1.9. We can now ditch the arrow thingy and write the same exact code as follows:

#calling the method:
my_method(val1, val2, { option2: "opt val 2", something: "whatever"} )
# simplified syntax
my_method(val1, val2, option2: "opt val 2", something: "whatever")

The first syntax is identical to what you'd use in JavaScript. The second one is the same of named parameters in C# 4. I thought this was a welcome coincidence. See the C# 4 version below.

//NOTE: C# 4 code
void my_method(string arg1, string arg2, 
      string option1 = "default 1", string option2 = "default 2",
      string something = "")
{
  // ... method body here ...
}

//calling the method:
my_method(val1, val2, option2: "opt val 2", something: "whatever");