Reputation: 10434
Say I have a method that takes in a string and an options hash. The options hash has method names as keys, and boolean / values as values.
some_method("foo", upcase: true, times: 5)
What this method should do is take the string, and run certain methods on the string based on the options hash, in this case, it should make the string upcase, then multiple it by 5. We get FOOFOOFOOFOOFOO
as the output.
The problem I am having is when I use the send
method, some of the methods from the options
hash require arguments (such as *
, and some do not (such as 'upcase').
Here is what I have so far.
def method(string, options = {})
options.each do |method_name, arg|
method_name = :* if method_name == :times
mod_string = mod_string.send(method_name, arg)
end
end
I get an error as expected
wrong number of arguments (given 1, expected 0)
(repl):9:in `upcase'
So, my question is: is there a way to only send the argument when there is an argument?
The only thing I came up with is use a if
statement to check for boolean values
options.each do |method_name, arg|
method_name = :* if method_name == :times
if arg == true
mod_string = mod_string.send(method_name)
elsif !(!!arg == arg)
mod_string = mod_string.send(method_name, arg)
end
end
I just want to see if there is a better way.
Upvotes: 0
Views: 325
Reputation: 198314
"When a method has one required argument, call it":
method = mod_string.method(method_name)
arity = method.arity
case arity
when 1, -1
method.call(arg)
when 0
method.call
else
raise "Method requires #{arity} arguments"
end
A probably better way would be to restructure your hash, and give it exactly the arguments you want to pass as an array:
some_method("foo", upcase: [], times: [5])
then you can simply mod_string.send(method_name, *arg)
.
Upvotes: 1