[rspec-users] [RSpec] Cloning objects and leaking state

Pat Maddox pergesu at gmail.com
Wed Jan 28 12:12:28 EST 2009

On Wed, Jan 28, 2009 at 8:30 AM, Nick Hoffman <nick at deadorange.com> wrote:
> On 28/01/2009, at 7:50 AM, Zach Dennis wrote:
>> On Tue, Jan 27, 2009 at 2:48 PM, Nick Hoffman <nick at deadorange.com> wrote:
>>> G'day folks. I've been beating my head on this one problem for a couple
>>> of
>>> hours, and have managed to figure out what's causing it. However, I don't
>>> understand why it's happening, nor do I know how to solve or get around
>>> it.
>>> One of my methods clones an arg, and it seems that doing so causes state
>>> to
>>> leak out. I discovered this because changing this:
>>> new_subtitle = subtitle.clone
>>> to this:
>>> new_subtitle = subtitle
>>> causes the problem to disappear.
>>> Before we get into the code snippets, are there any known caveats,
>>> warnings,
>>> or problems with writing specs that cover the cloning or duplication of
>>> objects?
>>> Here's the code, specs, and spec output:
>>> http://gist.github.com/53482
>>> As you can see, in the "should clone ..." example, the expectation on
>>> line
>>> 24 succeeds, but the same expectation on line 28 fails. After that, the
>>> same
>>> expectation fails in the "should not leak state" example.
>> What does your full SubtitleFile class look like? It looks like there
>> is an issue with how the #subtitles method is storing information.
>> Since you're using ActiveRecord::BaseWithoutTable there are probably
>> not going to be any unique primary keys amongst your SubtitleFiles to
>> help differentiate them. So if #subtitles is a has_many, every call to
>> SubtitleFile#subtitles may lookup Subtitles in the exact same way w/o
>> any unique key to use to differentiate which subtitles belong to which
>> subtitle files which would produce the results you are seeing.
>> Is Subtitle a ActiveRecord::BaseWithoutTable or a real ActiveRecord::Base
>> model?
> Hi Zach. Subtitle is an ActiveRecord::BaseWithoutTable model; it does not
> inherit from ActiveRecord::Base .
> The SubtitleFile "subtitles" attribute is actually just an Array. I didn't
> bother to setup a has_many relationship with Subtitle.
> SubtitleFile#subtitles is a standard getter method that ActiveRecord sets up
> for me.
> In my app's console, I tested out a has_many relationship between two
> ActiveRecord::BaseWithoutTable models, and there weren't any mixups after
> creating associations between different model instances.
> Here's the source for the SubtitleFile model. The #add_subtitle! in question
> starts on line 74:
> http://gist.github.com/54028

I'm not familiar with this library, so I can't say for sure, but the line
default :subtitles => []
looks very suspicious to me.

The underlying library code would have to do a .clone of that default
value, otherwise all instances will share the same array (meaning if
you push a value onto it, the next instance will have that array with
one element).

If it doesn't automatically clone (it may, I don't know), it probably
should provide a lambda syntax so you can do:
default :subtitles => lambda { [] }


More information about the rspec-users mailing list