How can I call a method dynamically when its name is contained in a string variable? For example:
class MyClass
def foo; end
def bar; end
end
obj = MyClass.new
str = get_data_from_user # e.g. `gets`, `params`, DB access, etc.
str #=> "foo"
# somehow call `foo` on `obj` using the value in `str`.
How can I do this? Is doing so a security risk?
What you want to do is called dynamic dispatch. It’s very easy in Ruby, just use public_send
:
method_name = 'foobar'
obj.public_send(method_name) if obj.respond_to? method_name
If the method is private/protected, use send
instead, but prefer public_send
.
This is a potential security risk if the value of method_name
comes from the user. To prevent vulnerabilities, you should validate which methods can be actually called. For example:
if obj.respond_to?(method_name) && %w[foo bar].include?(method_name)
obj.send(method_name)
end