@@ -12,6 +12,7 @@ class << self
1212 attr_reader :route_set
1313 attr_reader :versions
1414 attr_reader :routes
15+ attr_reader :settings
1516
1617 def logger ( logger = nil )
1718 if logger
@@ -22,7 +23,7 @@ def logger(logger = nil)
2223 end
2324
2425 def reset!
25- @settings = [ { } ]
26+ @settings = Grape :: Util :: HashStack . new
2627 @route_set = Rack ::Mount ::RouteSet . new
2728 @prototype = nil
2829 end
@@ -31,40 +32,22 @@ def call(env)
3132 logger . info "#{ env [ 'REQUEST_METHOD' ] } #{ env [ 'PATH_INFO' ] } "
3233 route_set . freeze . call ( env )
3334 end
34-
35- # Settings are a stack, so when we
36- # want to access them they are merged
37- # in the order pushed.
38- def settings
39- @settings . inject ( { } ) { |f , h | f . merge! ( h ) ; f }
40- end
41-
42- def settings_stack
43- @settings
44- end
45-
35+
4636 # Set a configuration value for this namespace.
4737 #
4838 # @param key [Symbol] The key of the configuration variable.
4939 # @param value [Object] The value to which to set the configuration variable.
5040 def set ( key , value )
51- @ settings. last [ key . to_sym ] = value
41+ settings [ key . to_sym ] = value
5242 end
53-
43+
5444 # Add to a configuration value for this
5545 # namespace.
5646 #
5747 # @param key [Symbol] The key of the configuration variable.
5848 # @param value [Object] The value to which to set the configuration variable.
59- def add ( key , value )
60- current = @settings . last [ key . to_sym ]
61- if current . is_a? ( Array )
62- current . concat ( value )
63- elsif current . is_a? ( Hash )
64- current . merge! ( value )
65- else
66- @settings . last [ key . to_sym ] = value
67- end
49+ def imbue ( key , value )
50+ settings . imbue ( key , value )
6851 end
6952
7053 # Define a root URL prefix for your entire
@@ -137,12 +120,12 @@ def default_error_status(new_status = nil)
137120 def rescue_from ( *args , &block )
138121 if block_given?
139122 args . each do |arg |
140- add ( :rescue_handlers , { arg => block } )
123+ imbue ( :rescue_handlers , { arg => block } )
141124 end
142125 end
143- add ( :rescue_options , args . pop ) if args . last . is_a? ( Hash )
126+ imbue ( :rescue_options , args . pop ) if args . last . is_a? ( Hash )
144127 set ( :rescue_all , true ) and return if args . include? ( :all )
145- add ( :rescued_errors , args )
128+ imbue ( :rescued_errors , args )
146129 end
147130
148131 # Allows you to specify a default representation entity for a
@@ -167,12 +150,15 @@ def rescue_from(*args, &block)
167150 # @option options [Class] :with The entity class that will represent the model.
168151 def represent ( model_class , options )
169152 raise ArgumentError , "You must specify an entity class in the :with option." unless options [ :with ] && options [ :with ] . is_a? ( Class )
170- add ( :representations , model_class => options [ :with ] )
153+ imbue ( :representations , model_class => options [ :with ] )
171154 end
172155
173156 # Add helper methods that will be accessible from any
174157 # endpoint within this namespace (and child namespaces).
175158 #
159+ # When called without a block, all known helpers within this scope
160+ # are included.
161+ #
176162 # @example Define some helpers.
177163 # class ExampleAPI < Grape::API
178164 # helpers do
@@ -183,12 +169,12 @@ def represent(model_class, options)
183169 # end
184170 def helpers ( &block )
185171 if block_given?
186- m = settings_stack . last [ :helpers ] || Module . new
172+ m = settings . peek [ :helpers ] || Module . new
187173 m . class_eval &block
188174 set ( :helpers , m )
189175 else
190176 m = Module . new
191- settings_stack . each do |s |
177+ settings . stack . each do |s |
192178 m . send :include , s [ :helpers ] if s [ :helpers ]
193179 end
194180 m
@@ -272,13 +258,11 @@ def route(methods, paths = ['/'], route_options = {}, &block)
272258 end
273259
274260 def before ( &block )
275- settings_stack . last [ :befores ] ||= [ ]
276- settings_stack . last [ :befores ] << block
261+ settings . imbue ( :befores , [ block ] )
277262 end
278263
279264 def after ( &block )
280- settings_stack . last [ :afters ] ||= [ ]
281- settings_stack . last [ :afters ] << block
265+ settings . imbue ( :afters , [ block ] )
282266 end
283267
284268 def get ( paths = [ '/' ] , options = { } , &block ) ; route ( 'GET' , paths , options , &block ) end
@@ -293,7 +277,7 @@ def namespace(space = nil, &block)
293277 set ( :namespace , space . to_s ) if space
294278 end
295279 else
296- Rack ::Mount ::Utils . normalize_path ( settings_stack . map { |s | s [ :namespace ] } . join ( '/' ) )
280+ Rack ::Mount ::Utils . normalize_path ( settings . stack . map { |s | s [ :namespace ] } . join ( '/' ) )
297281 end
298282 end
299283
@@ -313,17 +297,17 @@ def scope(name = nil, &block)
313297 # to the current namespace and any children, but
314298 # not parents.
315299 #
316- # @param middleware_class [Class] The class of the middleware you'd like to inject.
300+ # @param middleware_class [Class] The class of the middleware you'd like
301+ # to inject.
317302 def use ( middleware_class , *args )
318- settings_stack . last [ :middleware ] ||= [ ]
319- settings_stack . last [ :middleware ] << [ middleware_class , *args ]
303+ settings . imbue ( :middleware , [ [ middleware_class , *args ] ] )
320304 end
321305
322306 # Retrieve an array of the middleware classes
323307 # and arguments that are currently applied to the
324308 # application.
325309 def middleware
326- settings_stack . inject ( [ ] ) { |a , s | a += s [ :middleware ] if s [ :middleware ] ; a }
310+ settings . stack . inject ( [ ] ) { |a , s | a += s [ :middleware ] if s [ :middleware ] ; a }
327311 end
328312
329313 # An array of API routes.
@@ -343,18 +327,18 @@ def versions
343327 def nest ( *blocks , &block )
344328 blocks . reject! { |b | b . nil? }
345329 if blocks . any?
346- settings_stack << { }
330+ settings . push # create a new context to eval the follow
347331 instance_eval &block if block_given?
348332 blocks . each { |b | instance_eval &b }
349- settings_stack . pop
333+ settings . pop # when finished, we pop the context
350334 else
351335 instance_eval &block
352336 end
353337 end
354338
355339 def aggregate_setting ( key )
356- settings_stack . inject ( [ ] ) do |befores , settings |
357- befores += ( settings [ key ] || [ ] )
340+ settings . stack . inject ( [ ] ) do |aggregate , frame |
341+ aggregate += ( frame [ key ] || [ ] )
358342 end
359343 end
360344
@@ -392,7 +376,13 @@ def build_endpoint(&block)
392376 def inherited ( subclass )
393377 subclass . reset!
394378 end
395-
379+
380+ def inherit ( other_stack )
381+ # settings stack should know how to merge aggregate keys / values
382+ # settings_stack.unshift *other_stack
383+ # raise settings_stack.inspect
384+ end
385+
396386 def route_set
397387 @route_set ||= Rack ::Mount ::RouteSet . new
398388 end
0 commit comments