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.