Reputation: 355484
I'm trying to dynamically define functions that call through to another function that takes an options parameter:
class MyClass
["hour", "minute", "second"].each do |interval|
define_method "get_#{interval}" do |args|
some_helper(interval, args)
end
end
def some_helper(interval, options={})
# Do something, with arguments
end
end
I'd like to be able to call the different methods on MyClass in these two ways (with and without optional arguments):
mc = MyClass.new
mc.get_minute( :first_option => "foo", :second_option => "bar")
mc.get_minute # This fails with: warning: multiple values for a block parameter (0 for 1)
On the second call to minute, I see this warning:
warning: multiple values for a block parameter (0 for 1)
Upvotes: 7
Views: 6251
Reputation: 27845
Two years later... I don't know if is is a new feature with ruby 1.9.2, or if it was also possible in the past, but this works:
class MyClass
["hour", "minute", "second"].each do |interval|
define_method "get_#{interval}" do |args = {:first_option => "default foo", :second_option => "default bar"}|
some_helper(interval, args)
end
end
def some_helper(interval, options={})
# Do something, with arguments
p options
end
end
mc = MyClass.new
mc.get_minute( :first_option => "foo", :second_option => "bar")
mc.get_minute
Result is:
{:first_option=>"foo", :second_option=>"bar"}
{:first_option=>"default foo", :second_option=>"default bar"}
Upvotes: 5
Reputation: 119
I agree with Gordon adding * to your args will make it go away.
Another way of doing this is to use method_missing()
Something like this:
class MyClass
def method_missing(m, *args)
if /get_(.+)/.match(m.to_s)
some_helper($1, args)
else
raise 'Method not found...'
end
end
def some_helper(interval, *args)
puts interval + ' -> ' + args.inspect
end
end
m = MyClass.new
m.get_minute( :first_option => "foo", :second_option => "bar" )
Upvotes: 0
Reputation: 26384
The only change you need to make is to change args
to *args
. The *
indicates that args
will contain an array of optional arguments to the block.
Upvotes: 16