danlee
danlee

Reputation: 733

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"

Upvotes: 7

Views: 3711

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230296

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"

Upvotes: 15

Michael Kohl
Michael Kohl

Reputation: 66837

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]

Upvotes: 2

Related Questions