Dynamic Class Loading/Unloading in Ruby

A recent project at work required a look at Ruby's facilities for dynamically loading, and more importantly, unloading classes. Here are the basic steps for taking a serialized-to-string class def and loading it, then unloading it...

First, let's define a class in a string . . .


 my_class_def= <<-EOS
 class MyClassFoo 

  def hello()
    puts "Hello Foo!" 
  end

 end
 EOS	

Next, let's load this class definition, by using class_eval . . .

 
 Object.class_eval my_class_def
		

Now, let's try and instantiate and access our class . . .

	
  foo=MyClassFoo.new
  foo.hello		

. . . we should see "Hello Foo!" printed by our new class instance.

Having loaded a class dynamically into the current runtime, we will now try to unload that class definition. To do this, we will call the private method remove_const, passing the constant's name (the name of our class, in this case) to remove that definition from the current runtime's list of constants . . .


 Object.send(:remove_const, "MyClassFoo")

. . . now let's try to create a new instance of MyClassFoo . . .

 bar=MyClassFoo.new

. . . you should get the following exception raised by the runtime: NameError: uninitialized constant MyClassFoo. This is expected, as having removed the class's name from the runtime's list of constants "MyClassFoo" no longer resolves to any defined object. But what about our previous instance of MyClassFoo? The instance foo? Let's see what happens when we try and access it . . .

  foo.hello		
	
. . . once again we should see "Hello Foo!" printed. It is important to note that while the underlying class defintion is no longer accessible, previous instances are still available and unmodified in their behavior.