On Sat, Oct 22, 2005 at 12:14:42AM +0900, Florian Weber wrote:
> Thanks, Paul. Unfortunately it doesn't seem to work for me:
> 
> class Bar
> end
> 
> class Foo < Bar
> end
> 
> Object.class_eval do
>    remove_const :Foo
>    const_set :Foo, Class.new(Bar) { }
> end
> GC.start
> 
> class Foo < Bar
> end
> 
> ObjectSpace.each_object(Class) do |klass|
>     puts klass if Bar > klass
> end

Your test looks odd to me.  First you create Foo.  Next you destroy it with
remove_const and const_set, but the class you set Foo to also inherits from
Bar.  The next section of code has no effect, because Foo already
exists.  Lastly you check to see if there are any classes that inherit
from Bar, which will of course be true, because Foo still inherits from
Bar.

Your other problem is that the original Foo class is probably still on
the stack, and the GC is picking that up.  So here's a fixed test:

  class Bar
  end

  def create_Foo(n=1000)
    return create_Foo(n-1) if n > 0
    eval "class Foo < Bar; end"
  end
  create_Foo

  Object.class_eval do
     remove_const :Foo
     const_set :Foo, Class.new
  end
  GC.start

  ObjectSpace.each_object(Class) do |klass|
    puts klass if Bar > klass
  end

Paul