>>>>> "C" == Chris Pine <nemo / hellotree.com> writes:

C> ...then the rest of the code *does* delete the class!

 Well, you are just seeing that the GC is conservative.

 Imagine that something write

   class A
   end

   a = A.new
   Object.module_eval { remove_const 'A' }

 at this step, ruby can't remove completely the class because this class is
 referenced by the object `a'

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   def a
      puts "a"
   end
end

a = A.new

Object.module_eval { remove_const 'A' }
class A
   def b
      puts "b"
   end
end

b = A.new
a.a
b.b
b.a
pigeon% 

pigeon% b.rb
a
b
./b.rb:20: undefined method `a' for #<A:0x401ad338> (NameError)
pigeon% 

 This is something similar in your case, because it exist a *temporary*
 variable which still make reference to the class

C> I just went through all of that in my mail "all the pretty evals..."; I was
C> asking if these are the same.  Obviously they aren't the same.

 Well apparently there is another problem :-)

 Just try this

pigeon% ruby -e 'class A; end; A.module_eval "12"'
pigeon% 

pigeon% ruby -e '[].module_eval "12"'
-e:1: undefined method `module_eval' for []:Array (NameError)
pigeon% 

 #module_eval is a method defined in Module, and only object which inherit
  from Module can access this method.

 Now

pigeon% ruby -e 'class A; end; A.instance_eval "12"'
pigeon%
 
pigeon% ruby -e '[].instance_eval "12"'
pigeon% 

 #instance_eval is defined in Kernel and *all* objects can use this method.

 You have 2 methods with differents names and defined in 2 differents
 classes. 

 Now

pigeon% ruby -e 'class A; end; A.eval "12"'
-e:1: private method `eval' called for A:Class (NameError)
pigeon%
 
pigeon% ruby -e '[].eval "12"'
-e:1: private method `eval' called for []:Array (NameError)
pigeon% 

 #eval is a module function of Kernel

 Now to see the difference

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   def A.a
      puts "A::a"
   end

   def a
      puts "A#a"
   end
end

def a
   puts "Object#a"
end

x = A.new

eval 'p self; a'

x.instance_eval 'p self; a'

class A
   eval 'p self; a'
end

A.instance_eval 'p self; a'
pigeon% 

pigeon% b.rb
main
Object#a
#<A:0x401ad1e4>
A#a
A
A::a
A
A::a
pigeon% 



Guy Decoux