Class: Otto::Route

Inherits:
Object
  • Object
show all
Defined in:
lib/otto.rb

Overview

e.g.

GET   /uri/path      YourApp.method
GET   /uri/path2     YourApp#method

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(verb, path, definition) ⇒ Route

Returns a new instance of Route.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/otto.rb', line 211

def initialize verb, path, definition
  @verb, @path, @definition = verb.to_s.upcase.to_sym, path, definition
  @pattern, @keys = *compile(@path)
  if !@definition.index('.').nil?
    @klass, @name = @definition.split('.')
    @kind = :class
  elsif !@definition.index('#').nil?
    @klass, @name = @definition.split('#')
    @kind = :instance
  else
    raise ArgumentError, "Bad definition: #{@definition}"
  end
  @klass = eval(@klass)
  #@method = eval(@klass).method(@name)
end

Instance Attribute Details

#definitionObject (readonly)

Returns the value of attribute definition.



209
210
211
# File 'lib/otto.rb', line 209

def definition
  @definition
end

#keysObject (readonly)

Returns the value of attribute keys.



209
210
211
# File 'lib/otto.rb', line 209

def keys
  @keys
end

#kindObject (readonly)

Returns the value of attribute kind.



209
210
211
# File 'lib/otto.rb', line 209

def kind
  @kind
end

#klassObject (readonly)

Returns the value of attribute klass.



209
210
211
# File 'lib/otto.rb', line 209

def klass
  @klass
end

#methodObject (readonly)

Returns the value of attribute method.



209
210
211
# File 'lib/otto.rb', line 209

def method
  @method
end

#nameObject (readonly)

Returns the value of attribute name.



209
210
211
# File 'lib/otto.rb', line 209

def name
  @name
end

#ottoObject

Returns the value of attribute otto.



210
211
212
# File 'lib/otto.rb', line 210

def otto
  @otto
end

#pathObject (readonly)

Returns the value of attribute path.



209
210
211
# File 'lib/otto.rb', line 209

def path
  @path
end

#patternObject (readonly)

Returns the value of attribute pattern.



209
210
211
# File 'lib/otto.rb', line 209

def pattern
  @pattern
end

#verbObject (readonly)

Returns the value of attribute verb.



209
210
211
# File 'lib/otto.rb', line 209

def verb
  @verb
end

Instance Method Details

#call(env, extra_params = {}) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/otto.rb', line 229

def call(env, extra_params={})
  extra_params ||= {}
  req = Rack::Request.new(env)
  res = Rack::Response.new
  req.extend Otto::RequestHelpers
  res.extend Otto::ResponseHelpers
  res.request = req
  req.params.merge! extra_params
  req.params.replace Otto::Static.indifferent_params(req.params)
  klass.extend Otto::Route::ClassMethods
  klass.otto = self.otto
  case kind
  when :instance
    inst = klass.new req, res
    inst.send(name)
  when :class
    klass.send(name, req, res)
  else
    raise RuntimeError, "Unsupported kind for #{@definition}: #{kind}"
  end
  res.body = [res.body] unless res.body.respond_to?(:each)
  res.finish
end

#compile(path) ⇒ Object



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/otto.rb', line 254

def compile(path)
  keys = []
  if path.respond_to? :to_str
    special_chars = %w{. + ( ) $}
    pattern =
      path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
        case match
        when "*"
          keys << 'splat'
          "(.*?)"
        when *special_chars
          Regexp.escape(match)
        else
          keys << $2[1..-1]
          "([^/?#]+)"
        end
      end
    # Wrap the regex in parens so the regex works properly.
    # They can fail when there's an | for example (matching only the last one).
    # Note: this means we also need to remove the first matched value.
    [/\A(#{pattern})\z/, keys]
  elsif path.respond_to?(:keys) && path.respond_to?(:match)
    [path, path.keys]
  elsif path.respond_to?(:names) && path.respond_to?(:match)
    [path, path.names]
  elsif path.respond_to? :match
    [path, keys]
  else
    raise TypeError, path
  end
end

#pattern_regexpObject



226
227
228
# File 'lib/otto.rb', line 226

def pattern_regexp
  Regexp.new(@path.gsub(/\/\*/, '/.+'))
end