rack-mount 0.0.1 → 0.6.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/README.rdoc +12 -4
  2. data/lib/rack/mount/analysis/frequency.rb +15 -6
  3. data/lib/rack/mount/analysis/histogram.rb +55 -6
  4. data/lib/rack/mount/analysis/splitting.rb +85 -71
  5. data/lib/rack/mount/code_generation.rb +117 -0
  6. data/lib/rack/mount/generatable_regexp.rb +95 -48
  7. data/lib/rack/mount/multimap.rb +2 -43
  8. data/lib/rack/mount/prefix.rb +12 -7
  9. data/lib/rack/mount/regexp_with_named_groups.rb +27 -7
  10. data/lib/rack/mount/route.rb +79 -18
  11. data/lib/rack/mount/route_set.rb +330 -22
  12. data/lib/rack/mount/strexp/parser.rb +0 -0
  13. data/lib/rack/mount/strexp/parser.y +34 -0
  14. data/lib/rack/mount/strexp/tokenizer.rb +83 -0
  15. data/lib/rack/mount/strexp/tokenizer.rex +12 -0
  16. data/lib/rack/mount/strexp.rb +54 -79
  17. data/lib/rack/mount/utils.rb +65 -174
  18. data/lib/rack/mount/vendor/multimap/multimap.rb +142 -39
  19. data/lib/rack/mount/vendor/multimap/multiset.rb +33 -1
  20. data/lib/rack/mount/vendor/multimap/nested_multimap.rb +18 -16
  21. data/lib/rack/mount/vendor/regin/regin/alternation.rb +40 -0
  22. data/lib/rack/mount/vendor/regin/regin/anchor.rb +4 -0
  23. data/lib/rack/mount/vendor/regin/regin/atom.rb +54 -0
  24. data/lib/rack/mount/vendor/regin/regin/character.rb +51 -0
  25. data/lib/rack/mount/vendor/regin/regin/character_class.rb +50 -0
  26. data/lib/rack/mount/vendor/regin/regin/collection.rb +77 -0
  27. data/lib/rack/mount/vendor/regin/regin/expression.rb +126 -0
  28. data/lib/rack/mount/vendor/regin/regin/group.rb +85 -0
  29. data/lib/rack/mount/vendor/regin/regin/options.rb +55 -0
  30. data/lib/rack/mount/vendor/regin/regin/parser.rb +521 -0
  31. data/lib/rack/mount/vendor/regin/regin/tokenizer.rb +0 -0
  32. data/lib/rack/mount/vendor/regin/regin/version.rb +3 -0
  33. data/lib/rack/mount/vendor/regin/regin.rb +75 -0
  34. data/lib/rack/mount/version.rb +3 -0
  35. data/lib/rack/mount.rb +13 -16
  36. metadata +73 -29
  37. data/lib/rack/mount/const.rb +0 -45
  38. data/lib/rack/mount/exceptions.rb +0 -3
  39. data/lib/rack/mount/generation/route.rb +0 -57
  40. data/lib/rack/mount/generation/route_set.rb +0 -163
  41. data/lib/rack/mount/meta_method.rb +0 -104
  42. data/lib/rack/mount/mixover.rb +0 -47
  43. data/lib/rack/mount/recognition/code_generation.rb +0 -99
  44. data/lib/rack/mount/recognition/route.rb +0 -59
  45. data/lib/rack/mount/recognition/route_set.rb +0 -88
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-mount
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 13
10
+ version: 0.6.13
5
11
  platform: ruby
6
12
  authors:
7
13
  - Joshua Peek
@@ -9,29 +15,53 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-07-12 00:00:00 -05:00
18
+ date: 2010-08-31 00:00:00 -05:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rack
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
23
34
  version: 1.0.0
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: multimap
27
35
  type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: racc
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
33
- version: 1.0.0
34
- version:
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rexical
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
35
65
  description: Stackable dynamic tree based Rack router
36
66
  email: josh@joshpeek.com
37
67
  executables: []
@@ -39,35 +69,43 @@ executables: []
39
69
  extensions: []
40
70
 
41
71
  extra_rdoc_files:
42
- - README.rdoc
43
72
  - LICENSE
73
+ - README.rdoc
44
74
  files:
75
+ - lib/rack/mount.rb
45
76
  - lib/rack/mount/analysis/frequency.rb
46
77
  - lib/rack/mount/analysis/histogram.rb
47
78
  - lib/rack/mount/analysis/splitting.rb
48
- - lib/rack/mount/const.rb
49
- - lib/rack/mount/exceptions.rb
79
+ - lib/rack/mount/code_generation.rb
50
80
  - lib/rack/mount/generatable_regexp.rb
51
- - lib/rack/mount/generation/route.rb
52
- - lib/rack/mount/generation/route_set.rb
53
- - lib/rack/mount/meta_method.rb
54
- - lib/rack/mount/mixover.rb
55
81
  - lib/rack/mount/multimap.rb
56
82
  - lib/rack/mount/prefix.rb
57
- - lib/rack/mount/recognition/code_generation.rb
58
- - lib/rack/mount/recognition/route.rb
59
- - lib/rack/mount/recognition/route_set.rb
60
83
  - lib/rack/mount/regexp_with_named_groups.rb
61
84
  - lib/rack/mount/route.rb
62
85
  - lib/rack/mount/route_set.rb
63
86
  - lib/rack/mount/strexp.rb
87
+ - lib/rack/mount/strexp/parser.rb
88
+ - lib/rack/mount/strexp/parser.y
89
+ - lib/rack/mount/strexp/tokenizer.rb
90
+ - lib/rack/mount/strexp/tokenizer.rex
64
91
  - lib/rack/mount/utils.rb
65
92
  - lib/rack/mount/vendor/multimap/multimap.rb
66
93
  - lib/rack/mount/vendor/multimap/multiset.rb
67
94
  - lib/rack/mount/vendor/multimap/nested_multimap.rb
68
- - lib/rack/mount.rb
69
- - README.rdoc
70
- - LICENSE
95
+ - lib/rack/mount/vendor/regin/regin.rb
96
+ - lib/rack/mount/vendor/regin/regin/alternation.rb
97
+ - lib/rack/mount/vendor/regin/regin/anchor.rb
98
+ - lib/rack/mount/vendor/regin/regin/atom.rb
99
+ - lib/rack/mount/vendor/regin/regin/character.rb
100
+ - lib/rack/mount/vendor/regin/regin/character_class.rb
101
+ - lib/rack/mount/vendor/regin/regin/collection.rb
102
+ - lib/rack/mount/vendor/regin/regin/expression.rb
103
+ - lib/rack/mount/vendor/regin/regin/group.rb
104
+ - lib/rack/mount/vendor/regin/regin/options.rb
105
+ - lib/rack/mount/vendor/regin/regin/parser.rb
106
+ - lib/rack/mount/vendor/regin/regin/tokenizer.rb
107
+ - lib/rack/mount/vendor/regin/regin/version.rb
108
+ - lib/rack/mount/version.rb
71
109
  has_rdoc: true
72
110
  homepage: http://github.com/josh/rack-mount
73
111
  licenses: []
@@ -78,21 +116,27 @@ rdoc_options: []
78
116
  require_paths:
79
117
  - lib
80
118
  required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
81
120
  requirements:
82
121
  - - ">="
83
122
  - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
84
126
  version: "0"
85
- version:
86
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
87
129
  requirements:
88
130
  - - ">="
89
131
  - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
90
135
  version: "0"
91
- version:
92
136
  requirements: []
93
137
 
94
- rubyforge_project: rack-mount
95
- rubygems_version: 1.3.5
138
+ rubyforge_project:
139
+ rubygems_version: 1.3.7
96
140
  signing_key:
97
141
  specification_version: 3
98
142
  summary: Stackable dynamic tree based Rack router
@@ -1,45 +0,0 @@
1
- module Rack::Mount
2
- module Const
3
- RACK_ROUTING_ARGS = 'rack.routing_args'.freeze
4
-
5
- begin
6
- eval('/(?<foo>.*)/').named_captures
7
- SUPPORTS_NAMED_CAPTURES = true
8
- REGEXP_NAMED_CAPTURE = '(?<%s>%s)'.freeze
9
- rescue SyntaxError, NoMethodError
10
- SUPPORTS_NAMED_CAPTURES = false
11
- REGEXP_NAMED_CAPTURE = '(?:<%s>%s)'.freeze
12
- end
13
-
14
- EMPTY_ARRAY = [].freeze
15
- EMPTY_HASH = {}.freeze
16
-
17
- NULL = "\0".freeze
18
-
19
- CONTENT_TYPE = 'Content-Type'.freeze
20
- CONTINUE = '100-continue'.freeze
21
- DELETE = 'PUT'.freeze
22
- EMPTY_STRING = ''.freeze
23
- EXPECT = 'Expect'.freeze
24
- GET = 'GET'.freeze
25
- HEAD = 'HEAD'.freeze
26
- PATH_INFO = 'PATH_INFO'.freeze
27
- POST = 'POST'.freeze
28
- PUT = 'PUT'.freeze
29
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
30
- SCRIPT_NAME = 'SCRIPT_NAME'.freeze
31
- SLASH = '/'.freeze
32
- TEXT_SLASH_HTML = 'text/html'.freeze
33
-
34
- DEFAULT_CONTENT_TYPE_HEADERS = {CONTENT_TYPE => TEXT_SLASH_HTML}.freeze
35
- HTTP_METHODS = [GET, HEAD, POST, PUT, DELETE].freeze
36
-
37
- OK = 'OK'.freeze
38
- NOT_FOUND = 'Not Found'.freeze
39
- EXPECTATION_FAILED = 'Expectation failed'.freeze
40
-
41
- OK_RESPONSE = [200, DEFAULT_CONTENT_TYPE_HEADERS, [OK].freeze].freeze
42
- NOT_FOUND_RESPONSE = [404, DEFAULT_CONTENT_TYPE_HEADERS, [NOT_FOUND].freeze].freeze
43
- EXPECTATION_FAILED_RESPONSE = [417, DEFAULT_CONTENT_TYPE_HEADERS, [EXPECTATION_FAILED].freeze].freeze
44
- end
45
- end
@@ -1,3 +0,0 @@
1
- module Rack::Mount
2
- class RoutingError < StandardError; end
3
- end
@@ -1,57 +0,0 @@
1
- require 'rack/mount/utils'
2
-
3
- module Rack::Mount
4
- module Generation
5
- module Route #:nodoc:
6
- attr_reader :generation_keys
7
-
8
- def initialize(*args)
9
- super
10
-
11
- @required_params = {}
12
- @required_defaults = {}
13
- @generation_keys = @defaults.dup
14
-
15
- @conditions.each do |method, condition|
16
- @required_params[method] = @conditions[method].required_captures.map { |s| s.name }.reject { |s| @defaults.include?(s) }.freeze
17
- @required_defaults[method] = @defaults.dup
18
- @conditions[method].captures.inject({}) { |h, s| h.merge!(s.to_hash) }.keys.each { |name|
19
- @required_defaults[method].delete(name)
20
- @generation_keys.delete(name) if @defaults.include?(name)
21
- }
22
- @required_defaults[method].freeze
23
- end
24
-
25
- @required_params.freeze
26
- @required_defaults.freeze
27
- @generation_keys.freeze
28
- end
29
-
30
- def generate(methods, params = {}, recall = {})
31
- if methods.is_a?(Array)
32
- result = methods.map { |m| generate_method(m, params, recall, @defaults) || (return nil) }
33
- else
34
- result = generate_method(methods, params, recall, @defaults)
35
- end
36
-
37
- if result
38
- @defaults.each do |key, value|
39
- params.delete(key) if params[key] == value
40
- end
41
- end
42
-
43
- result
44
- end
45
-
46
- private
47
- def generate_method(method, params, recall, defaults)
48
- merged = recall.merge(params)
49
- return nil unless condition = @conditions[method]
50
- return nil if condition.segments.empty?
51
- return nil unless @required_params[method].all? { |p| merged.include?(p) }
52
- return nil unless @required_defaults[method].all? { |k, v| merged[k] == v }
53
- condition.generate(params, recall, defaults)
54
- end
55
- end
56
- end
57
- end
@@ -1,163 +0,0 @@
1
- require 'rack/mount/utils'
2
- require 'forwardable'
3
-
4
- module Rack::Mount
5
- module Generation
6
- module RouteSet
7
- # Adds generation related concerns to RouteSet.new.
8
- def initialize(*args)
9
- @named_routes = {}
10
- @generation_key_analyzer = Analysis::Frequency.new
11
-
12
- super
13
- end
14
-
15
- # Adds generation aspects to RouteSet#add_route.
16
- def add_route(*args)
17
- route = super
18
- @named_routes[route.name] = route if route.name
19
- @generation_key_analyzer << route.generation_keys
20
- route
21
- end
22
-
23
- # Generates path from identifiers or significant keys.
24
- #
25
- # To generate a url by named route, pass the name in as a +Symbol+.
26
- # url(:dashboard) # => "/dashboard"
27
- #
28
- # Additional parameters can be passed in as a hash
29
- # url(:people, :id => "1") # => "/people/1"
30
- #
31
- # If no name route is given, it will fall back to a slower
32
- # generation search.
33
- # url(:controller => "people", :action => "show", :id => "1")
34
- # # => "/people/1"
35
- def url(*args)
36
- named_route, params, recall = extract_params!(*args)
37
-
38
- params = URISegment.wrap_values(params)
39
- recall = URISegment.wrap_values(recall)
40
-
41
- unless result = generate(:path_info, named_route, params, recall)
42
- return
43
- end
44
-
45
- uri, params = result
46
- params.each do |k, v|
47
- if v._value
48
- params[k] = v._value
49
- else
50
- params.delete(k)
51
- end
52
- end
53
-
54
- uri << "?#{Utils.build_nested_query(params)}" if uri && params.any?
55
- uri
56
- end
57
-
58
- def generate(method, *args) #:nodoc:
59
- raise 'route set not finalized' unless @generation_graph
60
-
61
- named_route, params, recall = extract_params!(*args)
62
- merged = recall.merge(params)
63
- route = nil
64
-
65
- if named_route
66
- if route = @named_routes[named_route.to_sym]
67
- recall = route.defaults.merge(recall)
68
- url = route.generate(method, params, recall)
69
- [url, params]
70
- else
71
- raise RoutingError, "#{named_route} failed to generate from #{params.inspect}"
72
- end
73
- else
74
- keys = @generation_keys.map { |key|
75
- if k = merged[key]
76
- k.to_s
77
- else
78
- nil
79
- end
80
- }
81
- @generation_graph[*keys].each do |r|
82
- if url = r.generate(method, params, recall)
83
- return [url, params]
84
- end
85
- end
86
-
87
- raise RoutingError, "No route matches #{params.inspect}"
88
- end
89
- end
90
-
91
- def rehash #:nodoc:
92
- @generation_keys = build_generation_keys
93
- @generation_graph = build_generation_graph
94
-
95
- super
96
- end
97
-
98
- private
99
- def expire!
100
- @generation_keys = @generation_graph = nil
101
- super
102
- end
103
-
104
- def build_generation_graph
105
- build_nested_route_set(@generation_keys) { |k, i|
106
- if k = @generation_key_analyzer.possible_keys[i][k]
107
- k.to_s
108
- else
109
- nil
110
- end
111
- }
112
- end
113
-
114
- def build_generation_keys
115
- @generation_key_analyzer.report
116
- end
117
-
118
- def extract_params!(*args)
119
- case args.length
120
- when 3
121
- named_route, params, recall = args
122
- when 2
123
- if args[0].is_a?(Hash) && args[1].is_a?(Hash)
124
- params, recall = args
125
- else
126
- named_route, params = args
127
- end
128
- when 1
129
- if args[0].is_a?(Hash)
130
- params = args[0]
131
- else
132
- named_route = args[0]
133
- end
134
- else
135
- raise ArgumentError
136
- end
137
-
138
- named_route ||= nil
139
- params ||= {}
140
- recall ||= {}
141
-
142
- [named_route, params.dup, recall.dup]
143
- end
144
-
145
- class URISegment < Struct.new(:_value)
146
- def self.wrap_values(hash)
147
- hash.inject({}) { |h, (k, v)| h[k] = new(v); h }
148
- end
149
-
150
- extend Forwardable
151
- def_delegators :_value, :==, :eql?, :hash
152
-
153
- def to_param
154
- @to_param ||= begin
155
- v = _value.respond_to?(:to_param) ? _value.to_param : _value
156
- Utils.escape_uri(v)
157
- end
158
- end
159
- alias_method :to_s, :to_param
160
- end
161
- end
162
- end
163
- end
@@ -1,104 +0,0 @@
1
- module Rack::Mount
2
- class MetaMethod #:nodoc:
3
- class Block < Array #:nodoc:
4
- def initialize(*parts)
5
- replace(parts)
6
- yield(self) if block_given?
7
- end
8
-
9
- def multiline?
10
- length > 1
11
- end
12
-
13
- def inspect(indented = 2)
14
- return Const::EMPTY_STRING if empty?
15
- space = ' ' * indented
16
- space + map { |p|
17
- if p.is_a?(Condition)
18
- p.inspect(indented)
19
- else
20
- p
21
- end
22
- }.join("\n#{space}")
23
- end
24
-
25
- def to_str
26
- map { |p| p.to_str }.join('; ')
27
- end
28
- end
29
-
30
- class Condition #:nodoc:
31
- attr_accessor :body, :else
32
-
33
- def initialize(*conditions)
34
- @conditions = conditions.map { |c| c.is_a?(Block) ? c : Block.new(c) }
35
- @body = Block.new
36
- @else = Block.new
37
- yield(@body) if block_given?
38
- end
39
-
40
- def <<(condition)
41
- @conditions << condition
42
- end
43
-
44
- def inspect(indented = 2)
45
- return @body.inspect(indented) if @conditions.empty?
46
- space = ' ' * indented
47
- str = 'if '
48
- str << @conditions.map { |b|
49
- b.multiline? ?
50
- "begin\n#{b.inspect(indented + 4)}\n#{space} end" :
51
- b.inspect(0)
52
- }.join(' && ')
53
- str << "\n#{@body.inspect(indented + 2)}" if @body.any?
54
- if @else.any?
55
- str << "\n#{space}else\n#{@else.inspect(indented + 2)}"
56
- end
57
- str << "\n#{space}end"
58
- str
59
- end
60
-
61
- def to_str
62
- return @body.to_str if @conditions.empty?
63
- str = 'if '
64
- str << @conditions.map { |b|
65
- b.multiline? ? "(#{b.to_str})" : b.to_str
66
- }.join(' && ')
67
- str << "; #{@body.to_str}" if @body.any?
68
- if @else.any?
69
- str << "; else; #{@else.to_str}"
70
- end
71
- str << "; end"
72
- str
73
- end
74
- end
75
-
76
- def initialize(sym, *args)
77
- @sym = sym
78
- @args = args
79
- @body = Block.new
80
- end
81
-
82
- def <<(line)
83
- @body << line
84
- end
85
-
86
- def inspect
87
- str = ""
88
- str << "def #{@sym}"
89
- str << "(#{@args.join(', ')})" if @args.any?
90
- str << "\n#{@body.inspect}" if @body.any?
91
- str << "\nend\n"
92
- str
93
- end
94
-
95
- def to_str
96
- str = []
97
- str << "def #{@sym}"
98
- str << "(#{@args.join(', ')})" if @args.any?
99
- str << "\n#{@body.to_str}" if @body.any?
100
- str << "\nend"
101
- str.join
102
- end
103
- end
104
- end
@@ -1,47 +0,0 @@
1
- module Rack::Mount
2
- # A mixin that changes the behavior of +include+. Instead of modules
3
- # being chained as a superclass, they are mixed into the objects
4
- # metaclass. This allows mixins to be stacked ontop of the instance
5
- # methods.
6
- module Mixover
7
- module InstanceMethods #:nodoc:
8
- def dup
9
- obj = super
10
- included_modules = (class << self; included_modules; end) - (class << obj; included_modules; end)
11
- included_modules.reverse.each { |mod| obj.extend(mod) }
12
- obj
13
- end
14
- end
15
-
16
- # Replaces include with a lazy version.
17
- def include(*mod)
18
- (@included_modules ||= []).push(*mod)
19
- end
20
-
21
- def new(*args, &block) #:nodoc:
22
- obj = allocate
23
- obj.extend(InstanceMethods)
24
- (@included_modules ||= []).each { |mod| obj.extend(mod) }
25
- obj.send(:initialize, *args, &block)
26
- obj
27
- end
28
-
29
- # Create a new class without an included module.
30
- def new_without_module(mod, *args, &block)
31
- old_included_modules = (@included_modules ||= []).dup
32
- @included_modules.delete(mod)
33
- new(*args, &block)
34
- ensure
35
- @included_modules = old_included_modules
36
- end
37
-
38
- # Create a new class temporarily with a module.
39
- def new_with_module(mod, *args, &block)
40
- old_included_modules = (@included_modules ||= []).dup
41
- include(mod)
42
- new(*args, &block)
43
- ensure
44
- @included_modules = old_included_modules
45
- end
46
- end
47
- end
@@ -1,99 +0,0 @@
1
- require 'rack/mount/meta_method'
2
-
3
- module Rack::Mount
4
- module Recognition
5
- module CodeGeneration #:nodoc:
6
- def _expired_call(env) #:nodoc:
7
- raise 'route set not finalized'
8
- end
9
-
10
- def rehash
11
- super
12
- optimize_call!
13
- end
14
-
15
- private
16
- def expire!
17
- class << self
18
- alias_method :call, :_expired_call
19
- end
20
-
21
- super
22
- end
23
-
24
- def optimize_container_iterator(container)
25
- m = MetaMethod.new(:optimized_each, :req)
26
- m << 'env = req.env'
27
-
28
- container.each_with_index { |route, i|
29
- path_info_unanchored = route.conditions[:path_info] &&
30
- !Utils.regexp_anchored?(route.conditions[:path_info])
31
- m << "route = self[#{i}]"
32
- m << 'routing_args = route.defaults.dup'
33
-
34
- m << matchers = MetaMethod::Condition.new do |body|
35
- body << "env[#{@parameters_key.inspect}] = routing_args"
36
- body << "response = route.app.call(env)"
37
- body << "return response unless response[0].to_i == 417"
38
- end
39
-
40
- route.conditions.each do |method, condition|
41
- matchers << MetaMethod::Block.new do |matcher|
42
- matcher << c = MetaMethod::Condition.new("m = req.#{method}.match(#{condition.inspect})") do |b|
43
- b << "matches = m.captures" if route.named_captures[method].any?
44
- route.named_captures[method].each do |k, i|
45
- b << MetaMethod::Condition.new("p = matches[#{i}]") do |c2|
46
- c2 << "routing_args[#{k.inspect}] = Utils.unescape_uri(p)"
47
- end
48
- end
49
- if method == :path_info && !Utils.regexp_anchored?(condition)
50
- b << "env[Prefix::KEY] = m.to_s"
51
- end
52
- b << "true"
53
- end
54
- c.else = MetaMethod::Block.new("false")
55
- end
56
- end
57
- }
58
-
59
- m << 'nil'
60
- # puts "\n#{m.inspect}"
61
- container.instance_eval(m, __FILE__, __LINE__)
62
- end
63
-
64
- def optimize_call!
65
- method = MetaMethod.new(:call, :env)
66
-
67
- if @routes.empty?
68
- method << 'env[Const::EXPECT] != Const::CONTINUE ? Const::NOT_FOUND_RESPONSE : Const::EXPECTATION_FAILED_RESPONSE'
69
- else
70
- method << 'begin'
71
- method << 'set_expectation = env[Const::EXPECT] != Const::CONTINUE'
72
- method << 'env[Const::EXPECT] = Const::CONTINUE if set_expectation'
73
-
74
- method << 'env[Const::PATH_INFO] = Utils.normalize_path(env[Const::PATH_INFO])'
75
- method << "req = #{@request_class.name}.new(env)"
76
- cache = false
77
- keys = @recognition_keys.map { |key|
78
- if key.is_a?(Array)
79
- cache = true
80
- key.call_source(:cache, :req)
81
- else
82
- "req.#{key}"
83
- end
84
- }.join(', ')
85
- method << 'cache = {}' if cache
86
- method << "container = @recognition_graph[#{keys}]"
87
- method << "optimize_container_iterator(container) unless container.respond_to?(:optimized_each)"
88
- method << "container.optimized_each(req) || (set_expectation ? Const::NOT_FOUND_RESPONSE : Const::EXPECTATION_FAILED_RESPONSE)"
89
- method << 'ensure'
90
- method << 'env.delete(Const::EXPECT) if set_expectation'
91
- method << 'end'
92
- end
93
-
94
- # puts "\n#{method.inspect}"
95
- instance_eval(method, __FILE__, __LINE__)
96
- end
97
- end
98
- end
99
- end