Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a class at run time within a module/namespace

Creating a class at runtime is done as follows:

klass = Class.new superclass, &block
Object.const_set class_name, klass

Example:

class Person
  def name
    "Jon"
  end
end

klass = Class.new Person do
  def name
    "#{super} Doe"
  end
end

Object.const_set "Employee", klass

puts Employee.new.name # prints "Jon Doe"

Now, let's say that you have a module called Company:

module Company
end

How do you create the Employee class at runtime within the Company module/namespace such that the following yields the same result?

puts Company::Employee.new.name # prints "Jon Doe"
like image 801
danlee Avatar asked Jun 24 '12 11:06

danlee


2 Answers

Easier than you think :)

Company.const_set "Employee", klass

When you set something on Object, it becomes global because, well, everything is an Object. But you can do const_set to every class/module. And remember, modules/classes are just constants. So, Company::Employee is a constant Employee in a constant Company. It's simple :)

Full code:

class Person
  def name
    "Jon"
  end
end

klass = Class.new Person do
  def name
    "#{super} Doe"
  end
end

module Company
end

Company.const_set "Employee", klass

Company::Employee.new.name # => "Jon Doe"
like image 79
Sergio Tulentsev Avatar answered Sep 20 '22 05:09

Sergio Tulentsev


You already had all the necessary pieces:

class Person
  def name
    "Jon"
  end
end

klass = Class.new Person do
  def name
    "#{super} Doe"
  end
end

module Company
end

Company.const_set "Employee", klass

puts Company::Employee.new.name # prints "Jon Doe"

Company.constants.grep(/Emp/)
#=> [:Employee]
like image 35
Michael Kohl Avatar answered Sep 22 '22 05:09

Michael Kohl