How to call methods dynamically based on their name? [duplicate]

ghz 1years ago ⋅ 4251 views

Question

This question already has answers here :

[Calling a Method From a String With the Method's Name in Ruby](/questions/1407451/calling-a-method-from-a-string-with-the-methods-name- in-ruby) (4 answers)

Closed 4 years ago.

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?


Answer

What you want to do is called dynamic dispatch. It’s very easy in Ruby, just use [public_send](http://ruby-doc.org/core/Object.html#method-i- public_send):

method_name = 'foobar'
obj.public_send(method_name) if obj.respond_to? method_name

If the method is private/protected, use [send](http://ruby- doc.org/core/Object.html#method-i-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