Hi!

I was just talking to @dchelimsky over Twitter about a weird corner case we've 
run into on 1.3.1 (I've also been able to reproduce it in 1.3.2)

So we're using this gem called ClassyStruct that's a higher performing 
OpenStruct:
https://github.com/amikula/classy_struct

Basically it acts the same as OpenStruct but defines methods on the object's 
class instead of the object itself on the fly.
When it receives a call that hits method_missing it calls attr_accessor on the 
method name then passes the call on to the object.

Our problem comes from having one spec that stubs out a call to the object:
foo.stub! :bar => 'test'

and later in another spec file trying to set the same method with a value then 
having our code use that value:
# spec
foo.bar = 'other test'
# code
puts "#{foo.bar} baz"

So our expectation is that foo.bar will return 'other test'. Instead it hits 
the old stub on foo which calls method_missing which is picked up again by 
ClassyStruct causing it to fire off attr_accessor again then passing the method 
through causing the stub to call method_missing and on and on finally giving us 
a "stack level too deep" error.

The crux of the problem is that ClassyStruct is adding a method to the class 
after Rspec has added the same method to the instance.

As I said it's a very weird corner case because we're calling attr_accessor on 
a class that already has objects floating around. The easiest way to fix this 
is to use stub! in both places.

Regardless we were surprised that the proxy sticks around after a test run. 
What is the reason for keeping it around?


Thanks for your time!
Doug McInnes
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to