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

Rick DeNatale rick.denatale at gmail.com
Wed Aug 4 20:34:15 EDT 2010


On Wed, Aug 4, 2010 at 12:41 PM, Bruno Cardoso <lists at ruby-forum.com> wrote:
> Hi,
>
> I have a function that adds dynamic validations to my models. I use a
> combination of ":remove_const" and "load" methods to reload the code
> everytime I want to re-apply my dynamic validations. It seams RSpec has
> some issues with this.
>
> I posted here a simpler example code that shows what I mean:
>
> http://pastie.org/private/ruvgxgipxfge6yzuudbq
>
> Is it possible to test this with RSpec?


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
-- 
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale


More information about the rspec-users mailing list