Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically define named classes in Ruby

I am writing an internal DSL in Ruby. For this, I need to programmatically create named classes and nested classes. What is the best way to do so? I recon that there are two ways to do so:

  1. Use Class.new to create an anonymous class, then use define_method to add methods to it, and finally call const_set to add them as named constants to some namespace.
  2. Use some sort of eval

I've tested the first way and it worked, but being new to Ruby, I am not sure that putting classes as constants is the right way.

Are there other, better ways? If not, which of the above is preferable?

like image 857
Little Bobby Tables Avatar asked Jul 05 '11 13:07

Little Bobby Tables


1 Answers

If you want to create a class with a dynamic name, you'll have to do almost exactly what you said. However, you do not need to use define_method. You can just pass a block to Class.new in which you initialize the class. This is semantically identical to the contents of class/end.

Remember with const_set, to be conscientious of the receiver (self) in that scope. If you want the class defined globally you will need to call const_set on the TopLevel module (which varies in name and detail by Ruby).

a_new_class = Class.new(Object) do   attr_accessor :x    def initialize(x)     print #{self.class} initialized with #{x}"     @x = x   end end  SomeModule.const_set("ClassName", a_new_class)  c = ClassName.new(10)  ... 
like image 100
Dylan Lukes Avatar answered Oct 03 '22 15:10

Dylan Lukes