[rspec-users] [RSpec] Dynamic reloading with Object.send(:remove_const)

Bruno Cardoso lists at ruby-forum.com
Thu Aug 5 05:16:35 EDT 2010


Rick Denatale wrote:
> Your pastie says
> # this should have made "Account" go back to its original state but
> it's not working.
> # this works outside of RSpec.
> 
> but I don't understand in what context.  In general this won't work in 
> Ruby.
> 
> Removing the constant only removes the constant from the internal hash
> which binds the name to the object value.  It doesn't change the class
> object (pointed to by the klass field) of existing instances.
> 
> Here's a little experiment. The defineFoo method should be the moral
> equivalent of the load, and the existence of the m2 method is an
> analogue to whether the class has the validation callback.
> 
> def defineFoo
>   eval("class Foo;def m1;end;end")
> end
> 
> defineFoo
> 
> foo = Foo.new
> 
> foo.methods - Object.instance_methods # => ["m1"]
> 
> Foo.class_eval("def m2;end")
> foo.methods - Object.instance_methods # => ["m1", "m2"]
> 
> Object.send(:remove_const, 'Foo')
> defineFoo
> 
> foo2 = Foo.new
> 
> foo2.methods - Object.instance_methods # => ["m1"]
> foo.methods - Object.instance_methods # => ["m1", "m2"]
> 
> foo.class == foo2.class # => false

Eureka!

You are absolutely right. I completly forgot that I need to instantiate 
the object again to have the updated definition of the class. Old 
instances remain the same even after the class definition is changed.

Thanks Rick.

-- 
Posted via http://www.ruby-forum.com/.


More information about the rspec-users mailing list