Ruby provides a mechanism for optional method parameters. However, this mechanism is not very flexible. Take look at the following example.
#!/usr/bin/env ruby
def my_method( a='Testing', b='this', c='feature' )
puts "#{a} #{b} #{c}"
end
my_method
my_method( 'Trying out' )
my_method( 'Testing', 'this great' )
Ruby does provide for default parameter values, but you can't specify them out of order or omit any of them. To define a new value for the parameters b, you have to re-state the default value for the a parameter. This requires you to know the default value of this parameter, which defeats one of the purposes of default parameter values.
What are more powerful and useful are named parameters. Named parameters can be passed in any order and you don't need to know their default values. While Ruby doesn't have any built-in support for named parameters, you can emulate them easily with hashes.
#!/usr/bin/env ruby
def my_method(opts={})
o = {
:a => 'Testing',
:b => 'this',
:c => 'feature'
}.merge(opts)
puts "#{o[:a]} #{o[:b]} #{o[:c]}"
end
my_method
my_method( :b => 'this great' )
While it is a bit more verbose to access the parameters, it is much more flexible. This works by merging the hash passed at the method call with the default parameters hash. A short variable name like o can be used for brevity, or a longer name like opts can be used for clarity.
If you're using ActiveSupport (in a Rails project, for example), you also have access to a method called reverse_merge!. This does the same thing as merge, only your defaults will be merged into the hash passed at method call. This allows you to define your options in a much more compact manner. Though either can be used to the same effect.
#!/usr/bin/env ruby
require 'activesupport'
def my_method( o={} )
o.reverse_merge! :a => 'Testing', :b => 'this', :c => 'feature'
puts "#{o[:a]} #{o[:b]} #{o[:c]}"
end
my_method
my_method( :b => 'this great' )

