0
@@ -6,19 +6,19 @@ require 'merb-core/dispatch/router/route'
0
# Router stores route definitions and finds the first
0
# route that matches the incoming request URL.
0
# Then information from route is used by dispatcher to
0
# call action on the controller.
0
# ==== Routes compilation.
0
# The most interesting method of Router (and heart of
0
# route matching machinery) is match method generated
0
# on the fly from routes definitions. It is called routes
0
# compilation. Generated match method body contains
0
# one if/elsif statement that picks the first matching route
0
# definition and sets values to named parameters of the route.
0
# Compilation is synchronized by mutex.
0
@@ -26,14 +26,14 @@ module Merb
0
@compiler_mutex = Mutex.new
0
@root_behavior = Behavior.new.defaults(:action => "index")
0
# Raised when route lookup fails.
0
class RouteNotFound < StandardError; end;
0
# Raised when parameters given to generation
0
# method do not match route parameters.
0
class GenerationError < StandardError; end;
0
class NotCompiledError < StandardError; end;
0
attr_accessor :routes, :named_routes, :resource_routes, :root_behavior
0
@@ -41,19 +41,20 @@ module Merb
0
# Creates a route building context and evaluates the block in it. A
0
# copy of +root_behavior+ (and instance of Behavior) is copied as
0
# An array containing routes that should be prepended to the routes
0
# defined in the block.
0
# An array containing routes that should be appended to the routes
0
# defined in the block.
0
# Returns self to allow chaining of methods.
0
def prepare(first = [], last = [], &block)
0
root_behavior._with_proxy(&block)
0
@@ -63,17 +64,23 @@ module Merb
0
# Appends route in the block to routing table.
0
prepare(routes, [], &block)
0
# Prepends routes in the block to routing table.
0
prepare([], routes, &block)
0
# Clears the routing table. Route generation and request matching
0
# won't work anymore until a new routing table is built.
0
alias_method :match, :match_before_compilation
0
@@ -84,18 +91,16 @@ module Merb
0
# Finds route matching URI of the request and returns a tuple of
0
# [route index, route params]. This method is called by the
0
# dispatcher and isn't as useful in applications.
0
# request<Merb::Request>:: request to match.
0
- # <Array(Integer, Hash)::
0
- # Two-tuple: route index and route parameters. Route
0
- # parameters are :controller, :action and all the named
0
- # segments of the route.
0
+ # Array[Integer, Hash]::
0
+ # Two-tuple: route index and route parameters. Route parameters
0
+ # are :controller, :action and all the named segments of the route.
0
def route_for(request) #:nodoc:
0
index, params = match(request)
0
route = routes[index] if index
0
@@ -105,43 +110,59 @@ module Merb
0
- # Just a placeholder for the compiled match method
0
+ # A placeholder for the compiled match method.
0
+ # This method is aliased as +match+ but this method gets overridden with
0
+ # the actual +match+ method (generated from the routes definitions) after
0
+ # being compiled. This method is only ever called before routes are
0
+ # NotCompiledError:: routes have not been compiled yet.
0
def match_before_compilation(request) #:nodoc:
0
raise NotCompiledError, "The routes have not been compiled yet"
0
alias_method :match, :match_before_compilation
0
# Generates a URL from the params
0
# The name of the route to generate
0
# anonymous_params<Object>::
0
# An array of anonymous parameters to generate the route
0
# with. These parameters are assigned to the route parameters
0
# in the order that they are passed.
0
# Named parameters to generate the route with.
0
# A hash of default parameters to generate the route with.
0
# This is usually the request parameters. If there are any
0
# required params that are missing to generate the route,
0
# they are pulled from this hash.
0
+ # url(:edit_node, node.id, :foo => "bar")
0
+ # url(:edit_site_rating, site.id, rating.id, :foo => "bar")
0
# String:: The generated URL
0
unless name.is_a?(Symbol)
0
unless route = Merb::Router.named_routes[name]
0
raise Merb::Router::GenerationError, "Named route not found: #{name}"
0
@@ -152,25 +173,25 @@ module Merb
0
# Generates a URL from the resource(s)
0
# resources<Symbol,Object>::
0
# The identifiers for the resource route to generate. These
0
# can either be symbols or objects. Symbols denote resource
0
# collection routes and objects denote the members.
0
# Any extra parameters needed to generate the route.
0
# String:: The generated URL
0
options = extract_options_from_args!(args) || {}
0
if arg.is_a?(Symbol) || arg.is_a?(String)
0
@@ -179,19 +200,21 @@ module Merb
0
unless route = Merb::Router.resource_routes[key]
0
raise Merb::Router::GenerationError, "Resource route not found: #{args.inspect}"
0
route.generate(params, defaults)
0
- # Defines method with a switch statement that does routes recognition.
0
+ # Compiles the routes and creates the +match+ method.
0
eval(compiled_statement, binding, "Generated Code for Router", 1)
0
@@ -199,18 +222,21 @@ module Merb
0
- # Generates method that does route recognition with a switch statement.
0
+ # Generates the method for evaluation defining a +match+ method to match
0
+ # a request with the defined routes.
0
@compiler_mutex.synchronize do
0
condition_keys, if_statements = Set.new, ""
0
routes.each_with_index do |route, i|
0
route.conditions.keys.each { |key| condition_keys << key }
0
if_statements << route.compiled_statement(i == 0)
0
statement = "def match(request)\n"
0
statement << condition_keys.inject("") do |cached, key|
0
cached << " cached_#{key} = request.#{key}.to_s\n"
0
@@ -222,7 +248,7 @@ module Merb