diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2009-05-14 09:28:11 +0800 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2009-05-16 00:29:56 +0800 |
commit | 0ab6b6c96dc43bec8a02d72ad5c6b944ad30df91 (patch) | |
tree | eb5691d2d9d3aa410f88af3519ae7d14e32ab145 | |
parent | 01c17705195577c2df955a606ccd9f4f4026756d (diff) | |
download | rack-0ab6b6c96dc43bec8a02d72ad5c6b944ad30df91.tar.gz |
Allow empty cascades. Reduce #call object allocation overhead. Speed up #include?
Signed-off-by: Joshua Peek <josh@joshpeek.com>
-rw-r--r-- | lib/rack/cascade.rb | 29 | ||||
-rw-r--r-- | test/spec_rack_cascade.rb | 8 |
2 files changed, 20 insertions, 17 deletions
diff --git a/lib/rack/cascade.rb b/lib/rack/cascade.rb index a038aa11..14c3e54d 100644 --- a/lib/rack/cascade.rb +++ b/lib/rack/cascade.rb @@ -4,31 +4,36 @@ module Rack # status codes). class Cascade + NotFound = [404, {}, []] + attr_reader :apps def initialize(apps, catch=404) - @apps = apps - @catch = [*catch] + @apps = []; @has_app = {} + apps.each { |app| add app } + + @catch = {} + [*catch].each { |status| @catch[status] = true } end def call(env) - status = headers = body = nil - raise ArgumentError, "empty cascade" if @apps.empty? - @apps.each { |app| - begin - status, headers, body = app.call(env) - break unless @catch.include?(status.to_i) - end - } - [status, headers, body] + result = NotFound + + @apps.each do |app| + result = app.call(env) + break unless @catch.include?(result[0].to_i) + end + + result end def add app + @has_app[app] = true @apps << app end def include? app - @apps.include? app + @has_app.include? app end alias_method :<<, :add diff --git a/test/spec_rack_cascade.rb b/test/spec_rack_cascade.rb index 3c0f3be3..cf3c29b4 100644 --- a/test/spec_rack_cascade.rb +++ b/test/spec_rack_cascade.rb @@ -28,15 +28,13 @@ context "Rack::Cascade" do Rack::MockRequest.new(cascade).get("/cgi/../bla").should.be.not_found end - specify "should fail if empty" do - lambda { Rack::MockRequest.new(Rack::Cascade.new([])).get("/") }. - should.raise(ArgumentError) + specify "should return 404 if empty" do + Rack::MockRequest.new(Rack::Cascade.new([])).get('/').should.be.not_found end specify "should append new app" do cascade = Rack::Cascade.new([], [404, 403]) - lambda { Rack::MockRequest.new(cascade).get('/cgi/test') }. - should.raise(ArgumentError) + Rack::MockRequest.new(cascade).get('/').should.be.not_found cascade << app2 Rack::MockRequest.new(cascade).get('/cgi/test').should.be.not_found Rack::MockRequest.new(cascade).get('/cgi/../bla').should.be.not_found |