Reputation: 132247
I want to change the default arguments passed to a Ruby function. For example, instead of each time writing
[1,2,3].do_stuff(:option => ' my option ')
I want to modify the defaults so that I can write
[1,2,3].do_stuff
What is the simplest, cleanest, most Ruby-like way of changing default parameters?
Upvotes: 3
Views: 336
Reputation: 14668
(moved from your original question)
I assume you are talking about a method Array#do_stuff that already exists, but you want to modify it slightly (in your case by changing a default parameter).
A post here gives a nice way of doing it. It doesn't suffer from the same problems as the alias technique, as there isn't a leftover "old" method.
Here how you could use that technique with your example problem (tested with ruby 1.9)
class Array
old_do_stuff = instance_method(:do_stuff)
define_method(:do_stuff) { |options = {}|
options[:option] ||= " option "
old_do_stuff.bind(self).call(options)
}
end
You might also want read up on UnboundMethod if the above code is confusing. Note that old_do_stuff goes out of scope after the end statement, so it isn't a problem for future uses of Array.
Upvotes: 1
Reputation: 12426
>> [1, 2, 3].do_stuff
=> Result I get
>> [1, 2, 3].do_stuff :an_option => a_value
=> Result I really want, but don't want to specify the argument
I like to use super
for this. It allows us to add some functionality to the method apart from just changing default arguments:
class Array
def do_stuff(options = {})
# Verify if caller has not passed the option
options[:argument_i_want_to_change] = default_value_i_want unless options.has_key? :argument_i_want_to_change
# call super
super
end
end
Result:
>> [1, 2, 3].do_stuff
=> Result that I really want
UPDATE: Removed reverse_merge! dependency. (Now looking for a better alternatives to using []= method)
Upvotes: 2
Reputation: 12782
Are you wanting a solution for code you didn't write yourself? There are two options I'm aware of.
Code you wrote yourself:
def some_method_you_wrote(options)
becomes:
def some_method_you_wrote(options = { :option1 => 'value' })
(Swanand's answer is nice too)
For code you didn't write, look into aliasing methods. (Rails provides something called alias_method_chain
for this purpose, IIRC.)
Upvotes: 0