# File lib/middleware/runner.rb, line 38 def build_call_chain(stack) # We need to instantiate the middleware stack in reverse # order so that each middleware can have a reference to # the next middleware it has to call. The final middleware # is always the empty middleware, which does nothing but return. stack.reverse.inject(EMPTY_MIDDLEWARE) do |next_middleware, current_middleware| # Unpack the actual item klass, args, block = current_middleware # Default the arguments to an empty array. Otherwise in Ruby 1.8 # a `nil` args will actually pass `nil` into the class. Not what # we want! args ||= [] if klass.is_a?(Class) # If the klass actually is a class, then instantiate it with # the app and any other arguments given. klass.new(next_middleware, *args, &block) elsif klass.respond_to?(:call) # Make it a lambda which calls the item then forwards up # the chain. lambda do |env| klass.call(env) next_middleware.call(env) end else raise "Invalid middleware, doesn't respond to `call`: #{action.inspect}" end end end