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.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/otto.rb', line 249

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.



247
248
249
# File 'lib/otto.rb', line 247

def definition
  @definition
end

#keysObject (readonly)

Returns the value of attribute keys.



247
248
249
# File 'lib/otto.rb', line 247

def keys
  @keys
end

#kindObject (readonly)

Returns the value of attribute kind.



247
248
249
# File 'lib/otto.rb', line 247

def kind
  @kind
end

#klassObject (readonly)

Returns the value of attribute klass.



247
248
249
# File 'lib/otto.rb', line 247

def klass
  @klass
end

#methodObject (readonly)

Returns the value of attribute method.



247
248
249
# File 'lib/otto.rb', line 247

def method
  @method
end

#nameObject (readonly)

Returns the value of attribute name.



247
248
249
# File 'lib/otto.rb', line 247

def name
  @name
end

#ottoObject

Returns the value of attribute otto.



248
249
250
# File 'lib/otto.rb', line 248

def otto
  @otto
end

#pathObject (readonly)

Returns the value of attribute path.



247
248
249
# File 'lib/otto.rb', line 247

def path
  @path
end

#patternObject (readonly)

Returns the value of attribute pattern.



247
248
249
# File 'lib/otto.rb', line 247

def pattern
  @pattern
end

#verbObject (readonly)

Returns the value of attribute verb.



247
248
249
# File 'lib/otto.rb', line 247

def verb
  @verb
end

Instance Method Details

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



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/otto.rb', line 267

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



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/otto.rb', line 292

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



264
265
266
# File 'lib/otto.rb', line 264

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