[response].flatten causes infinite loop #419

dchelimsky opened this Issue Aug 23, 2012 · 3 comments


None yet
5 participants
  • Rack::Response#finish is aliased with to_ary [1]
  • Rack::Response#finish returns an array including selfwhen the response code is anything other than 204, 205, 304 [2]

The result is an infinite loop if the result of app.call(env) (assigned to response in Rails' testing framework) is included in an array that is flattened. The reason is that Array#flatten invokes to_ary on each element that responds to to_ary, then does the same to the contents of the result of to_ary, and so on.

Because self is in the array returned by to_ary, it gets to_ary invoked and returns the same array, including self, which then gets to_ary invoked on it, which returns the same array, including self, and so on.


alias to_ary finish # For implicit-splat on Ruby 1.9.2

[status.to_i, header, self]

@ghost ghost assigned raggi Aug 26, 2012

@alindeman alindeman referenced this issue in rspec/rspec-rails Oct 3, 2012


Controller specs: response.should == 'string' #613

@raggi raggi closed this in 5b251a9 Nov 2, 2012

raggi added a commit that referenced this issue Jan 4, 2013

raggi added a commit that referenced this issue Jan 4, 2013

sdhull commented Oct 9, 2013

Be nice to release a version with this included. Ran into this yesterday with the latest available version of rack (by mistake of course) and had to restart my machine(!).

I'm having trouble understanding the resolution. Is this addressed in Rack 1.4.5? I'm running into some big memory leaks when running some specs.


jeremy commented Sep 13, 2014

The root issue here is that Response defines #to_ary at all.

The response object should be explicitly converted to an Array using #to_a. That allows for explicit splatting, too: status, headers, body = *response.

A response is not itself Array-like, though. [response, response].flatten does not make sense. response + response does not makes sense.

By eliminating Response#to_ary, this problem goes away, and the proxy workaround can be unwound, taking us back to simpler times ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment