Reputation: 1
what is the best way to create a method with a such behavior?
def foo(arg1, arg2, some_method_name)
arg1.some_method_name(arg2)
end
I know there should be some Ruby magic, simple and pure.
Upvotes: 0
Views: 66
Reputation: 13014
Will also suggest to rather have such method where you can supply variable arguments to method
def foo(arg1, method_name, *args)
arg1.public_send(method_name, *args) # dynamically dispatch the method with the relevant arguments
end
foo("kiddorails", :upcase) # KIDDORAILS
foo("kiddorails", :gsub, 's', '') # kiddorail
Upvotes: 0
Reputation: 1643
In Ruby, method calls are just messages sent to the object.
You're looking for
def foo(arg1, arg2, some_method_name)
arg1.send(some_method_name.to_s, arg2)
end
Note that this method can access both public and private methods of the class; this is probably desired for testing, but if you want it to fail for private methods, just use public_send
def foo(arg1, arg2, some_method_name)
arg1.public_send(some_method_name.to_s, arg2)
end
If you may have an existing send method defined on that object, just replace send
with __send__
See https://ruby-doc.org/core-2.5.1/Object.html#method-i-send for more information
Upvotes: 0
Reputation: 30056
Try Object#public_send
:
def foo(arg1, arg2, some_method_name)
arg1.public_send(some_method_name, arg2)
end
Upvotes: 4