Dynamic Class Definition WITH a Class Name

Mike Bethany picture Mike Bethany · Nov 6, 2010 · Viewed 33.6k times · Source

How do I dynamically define a class in Ruby WITH a name?

I know how to create a class dynamically without a name using something like:

dynamic_class = Class.new do
  def method1
  end
end

But you can't specify a class name. I want to create a class dynamically with a name.

Here's an example of what I want to do but of course it doesn't actually work.
(Note that I am not creating an instance of a class but a class definition)

class TestEval
  def method1
    puts "name: #{self.name}"
  end
end

class_name = "TestEval"
dummy = eval("#{class_name}")

puts "dummy: #{dummy}"

dynamic_name = "TestEval2"
class_string = """
class #{dynamic_name}
  def method1
  end
end
"""
dummy2 = eval(class_string)
puts "dummy2: #{dummy2}" # doesn't work

Actual output:

dummy: TestEval
dummy2: 

Desired output:

dummy: TestEval
dummy2: TestEval2

======================================================

Answer: A totally dynamic solution using sepp2k's method

dynamic_name = "TestEval2"

Object.const_set(dynamic_name, Class.new) # If inheriting, use Class.new( superclass )
dummy2 = eval("#{dynamic_name}")
puts "dummy2: #{dummy2}"

Answer

sepp2k picture sepp2k · Nov 6, 2010

The name of a class is simply the name of the first constant that refers to it.

I.e. if I do myclass = Class.new and then MyClass = myclass, the name of the class will become MyClass. However I can't do MyClass = if I don't know the name of the class until runtime.

So instead you can use Module#const_set, which dynamically sets the value of a const. Example:

dynamic_name = "ClassName"
Object.const_set(dynamic_name, Class.new { def method1() 42 end })
ClassName.new.method1 #=> 42