14

I'm trying to figure out how to dynamically create methods

class MyClass
  def initialize(dynamic_methods)
    @arr = Array.new(dynamic_methods)
    @arr.each { |m|
      self.class.class_eval do
        def m(*value) 
          puts value
        end
      end
    }
    end
end

tmp = MyClass.new ['method1', 'method2', 'method3']

Unfortunately this only creates the method m but I need to create methods based on the value of m, ideas?

2 Answers 2

28

There are two accepted ways:

  1. Use define_method:

    @arr.each do |method|
      self.class.class_eval do
        define_method method do |*arguments|
          puts arguments
        end
      end
    end
    
  2. Use class_eval with a string argument:

    @arr.each do |method|
      self.class.class_eval <<-EVAL
        def #{method}(*arguments)
          puts arguments
        end
      EVAL
    end
    

The first option converts a closure to a method, the second option evaluates a string (heredoc) and uses regular method binding. The second option has a very slight performance advantage when invoking the methods. The first option is (arguably) a little more readable.

Sign up to request clarification or add additional context in comments.

1 Comment

You might want to note that you need to be more careful about the second method, e.g. avoid code like github.com/rails/rails/blob/…
4
define_method(m) do |*values|
  puts value
end

3 Comments

Great, that works but how do I specify value as an optional parameter?
Oh just add a "*" to it like so? define_method(m) do |*value|
Right (I just edited it to that effect). Note though that *value doesn't mean "value is an optional argument". It means "value is an array containing all the arguments (of which there might be an arbitrary number).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.