Parent

Rack::Mount::RouteSet

Constants

X_CASCADE
PASS
PATH_INFO

Public Class Methods

new(options = {}, &block) click to toggle source

Basic RouteSet initializer.

If a block is given, the set is yielded and finalized.

See other aspects for other valid options:

  • Generation::RouteSet.new

  • Recognition::RouteSet.new

    # File lib/rack/mount/route_set.rb, line 21
21:     def initialize(options = {}, &block)
22:       @parameters_key = options.delete(:parameters_key) || 'rack.routing_args'
23:       @parameters_key.freeze
24: 
25:       @named_routes = {}
26: 
27:       @recognition_key_analyzer = Analysis::Splitting.new
28:       @generation_key_analyzer  = Analysis::Frequency.new
29: 
30:       @request_class = options.delete(:request_class) || Rack::Request
31:       @valid_conditions = @request_class.public_instance_methods.map! { |m| m.to_sym }
32: 
33:       extend CodeGeneration unless options[:_optimize] == false
34:       @optimized_recognize_defined = false
35: 
36:       @routes = []
37:       expire!
38: 
39:       if block_given?
40:         yield self
41:         rehash
42:       end
43:     end
new_without_optimizations(options = {}, &block) click to toggle source

Initialize a new RouteSet without optimizations

    # File lib/rack/mount/route_set.rb, line 10
10:     def self.new_without_optimizations(options = {}, &block)
11:       new(options.merge(:_optimize => false), &block)
12:     end

Public Instance Methods

add_route(app, conditions = {}, defaults = {}, name = nil) click to toggle source

Builder method to add a route to the set

app

A valid Rack app to call if the conditions are met.

conditions

A hash of conditions to match against. Conditions may be expressed as strings or regexps to match against.

defaults

A hash of values that always gets merged in

name

Symbol identifier for the route used with named route generations

    # File lib/rack/mount/route_set.rb, line 54
54:     def add_route(app, conditions = {}, defaults = {}, name = nil)
55:       unless conditions.is_a?(Hash)
56:         raise ArgumentError, 'conditions must be a Hash'
57:       end
58: 
59:       unless conditions.all? { |method, pattern|
60:           @valid_conditions.include?(method)
61:         }
62:         raise ArgumentError, 'conditions may only include ' +
63:           @valid_conditions.inspect
64:       end
65: 
66:       route = Route.new(app, conditions, defaults, name)
67:       @routes << route
68: 
69:       @recognition_key_analyzer << route.conditions
70: 
71:       @named_routes[route.name] = route if route.name
72:       @generation_key_analyzer << route.generation_keys
73: 
74:       expire!
75:       route
76:     end
call(env) click to toggle source

Rack compatible recognition and dispatching method. Routes are tried until one returns a non-catch status code. If no routes match, the catch status code is returned.

This method can only be invoked after the RouteSet has been finalized.

     # File lib/rack/mount/route_set.rb, line 132
132:     def call(env)
133:       raise 'route set not finalized' unless @recognition_graph
134: 
135:       env[PATH_INFO] = Utils.normalize_path(env[PATH_INFO])
136: 
137:       request = nil
138:       req = @request_class.new(env)
139:       recognize(req) do |route, matches, params|
140:         # TODO: We only want to unescape params from uri related methods
141:         params.each { |k, v| params[k] = Utils.unescape_uri(v) if v.is_a?(String) }
142: 
143:         if route.prefix?
144:           env[Prefix::KEY] = matches[:path_info].to_s
145:         end
146: 
147:         env[@parameters_key] = params
148:         result = route.app.call(env)
149:         return result unless result[1][X_CASCADE] == PASS
150:       end
151: 
152:       request || [404, {'Content-Type' => 'text/html', 'X-Cascade' => 'pass'}, ['Not Found']]
153:     end
freeze() click to toggle source

Finalizes the set and builds optimized data structures. You must freeze the set before you can use call and url. So remember to call freeze after you are done adding routes.

     # File lib/rack/mount/route_set.rb, line 261
261:     def freeze
262:       unless frozen?
263:         rehash
264: 
265:         @recognition_key_analyzer = nil
266:         @generation_key_analyzer  = nil
267:         @valid_conditions         = nil
268: 
269:         @routes.each { |route| route.freeze }
270:         @routes.freeze
271:       end
272: 
273:       super
274:     end
length() click to toggle source

Number of routes in the set

     # File lib/rack/mount/route_set.rb, line 243
243:     def length
244:       @routes.length
245:     end
recognize(obj) click to toggle source
     # File lib/rack/mount/route_set.rb, line 78
 78:     def recognize(obj)
 79:       raise 'route set not finalized' unless @recognition_graph
 80: 
 81:       cache = {}
 82:       keys = @recognition_keys.map { |key|
 83:         if key.respond_to?(:call)
 84:           key.call(cache, obj)
 85:         else
 86:           obj.send(key)
 87:         end
 88:       }
 89: 
 90:       @recognition_graph[*keys].each do |route|
 91:         matches = {}
 92:         params  = route.defaults.dup
 93: 
 94:         if route.conditions.all? { |method, condition|
 95:             value = obj.send(method)
 96:             if condition.is_a?(Regexp) && (m = value.match(condition))
 97:               matches[method] = m
 98:               captures = m.captures
 99:               route.named_captures[method].each do |k, i|
100:                 if v = captures[i]
101:                   params[k] = v
102:                 end
103:               end
104:               true
105:             elsif value == condition
106:               true
107:             else
108:               false
109:             end
110:           }
111:           if block_given?
112:             yield route, matches, params
113:           else
114:             return route, matches, params
115:           end
116:         end
117:       end
118: 
119:       nil
120:     end
url(env, *args) click to toggle source

Generates a url from Rack env and identifiers or significant keys.

To generate a url by named route, pass the name in as a Symbol.

  url(env, :dashboard) # => "/dashboard"

Additional parameters can be passed in as a hash

  url(env, :people, :id => "1") # => "/people/1"

If no name route is given, it will fall back to a slower generation search.

  url(env, :controller => "people", :action => "show", :id => "1")
    # => "/people/1"
     # File lib/rack/mount/route_set.rb, line 167
167:     def url(env, *args)
168:       named_route, params = nil, {}
169: 
170:       case args.length
171:       when 2
172:         named_route, params = args[0], args[1].dup
173:       when 1
174:         if args[0].is_a?(Hash)
175:           params = args[0].dup
176:         else
177:           named_route = args[0]
178:         end
179:       else
180:         raise ArgumentError
181:       end
182: 
183:       only_path = params.delete(:only_path)
184:       recall = env[@parameters_key] || {}
185: 
186:       unless result = generate(:all, named_route, params, recall,
187:           :parameterize => lambda { |name, param| Utils.escape_uri(param) })
188:         return
189:       end
190: 
191:       parts, params = result
192:       return unless parts
193: 
194:       params.each do |k, v|
195:         if v
196:           params[k] = v
197:         else
198:           params.delete(k)
199:         end
200:       end
201: 
202:       req = stubbed_request_class.new(env)
203:       req._stubbed_values = parts.merge(:query_string => Utils.build_nested_query(params))
204:       only_path ? req.fullpath : req.url
205:     end

Protected Instance Methods

recognition_stats() click to toggle source
     # File lib/rack/mount/route_set.rb, line 297
297:       def recognition_stats
298:         { :keys => @recognition_keys,
299:           :keys_size => @recognition_keys.size,
300:           :graph_size => @recognition_graph.size,
301:           :graph_height => @recognition_graph.height,
302:           :graph_average_height => @recognition_graph.average_height }
303:       end

Private Instance Methods

build_generation_graph() click to toggle source
     # File lib/rack/mount/route_set.rb, line 349
349:       def build_generation_graph
350:         build_nested_route_set(@generation_keys) { |k, i|
351:           throw :skip unless @routes[i].significant_params?
352: 
353:           if k = @generation_key_analyzer.possible_keys[i][k]
354:             k.to_s
355:           else
356:             nil
357:           end
358:         }
359:       end
build_generation_keys() click to toggle source
     # File lib/rack/mount/route_set.rb, line 361
361:       def build_generation_keys
362:         keys = @generation_key_analyzer.report
363:         Utils.debug "generation keys - #{keys.inspect}"
364:         keys
365:       end
build_nested_route_set(keys, &block) click to toggle source

An internal helper method for constructing a nested set from the linear route set.

build_nested_route_set([:request_method, :path_info]) { |route, method|

  route.send(method)

}

     # File lib/rack/mount/route_set.rb, line 324
324:       def build_nested_route_set(keys, &block)
325:         graph = Multimap.new
326:         @routes.each_with_index do |route, index|
327:           catch(:skip) do
328:             k = keys.map { |key| block.call(key, index) }
329:             Utils.pop_trailing_blanks!(k)
330:             k.map! { |key| key || /.*/ }
331:             graph[*k] = route
332:           end
333:         end
334:         graph
335:       end
build_recognition_graph() click to toggle source
     # File lib/rack/mount/route_set.rb, line 337
337:       def build_recognition_graph
338:         build_nested_route_set(@recognition_keys) { |k, i|
339:           @recognition_key_analyzer.possible_keys[i][k]
340:         }
341:       end
build_recognition_keys() click to toggle source
     # File lib/rack/mount/route_set.rb, line 343
343:       def build_recognition_keys
344:         keys = @recognition_key_analyzer.report
345:         Utils.debug "recognition keys - #{keys.inspect}"
346:         keys
347:       end
extract_params!(*args) click to toggle source
     # File lib/rack/mount/route_set.rb, line 367
367:       def extract_params!(*args)
368:         case args.length
369:         when 4
370:           named_route, params, recall, options = args
371:         when 3
372:           if args[0].is_a?(Hash)
373:             params, recall, options = args
374:           else
375:             named_route, params, recall = args
376:           end
377:         when 2
378:           if args[0].is_a?(Hash)
379:             params, recall = args
380:           else
381:             named_route, params = args
382:           end
383:         when 1
384:           if args[0].is_a?(Hash)
385:             params = args[0]
386:           else
387:             named_route = args[0]
388:           end
389:         else
390:           raise ArgumentError
391:         end
392: 
393:         named_route ||= nil
394:         params  ||= {}
395:         recall  ||= {}
396:         options ||= {}
397: 
398:         [named_route, params.dup, recall.dup, options.dup]
399:       end
instance_variables_to_serialize() click to toggle source
     # File lib/rack/mount/route_set.rb, line 314
314:       def instance_variables_to_serialize
315:         instance_variables.map { |ivar| ivar.to_sym } - [:@stubbed_request_class, :@optimized_recognize_defined]
316:       end
stubbed_request_class() click to toggle source
     # File lib/rack/mount/route_set.rb, line 401
401:       def stubbed_request_class
402:         @stubbed_request_class ||= begin
403:           klass = Class.new(@request_class)
404:           klass.public_instance_methods.each do |method|
405:             next if method =~ /^__|object_id/
406:             klass.class_eval               def #{method}(*args, &block)                @_stubbed_values[:#{method}] || super              end
407:           end
408:           klass.class_eval { attr_accessor :_stubbed_values }
409:           klass
410:         end
411:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.