lib/merb/merb_router.rb in merb-0.0.4 vs lib/merb/merb_router.rb in merb-0.0.5
- old
+ new
@@ -11,42 +11,59 @@
# the default /controller/action and /controller/action/id urls:
# r.add '/:class/:method/:id'
class RouteMatcher
attr_accessor :sections
- @@section_regexp = /(?::([a-z*]+))/.freeze
+ @@section_regexp = /(?::([a-z*_]+))/.freeze
+ # setup the router and yield it out to
+ # add routes to it. Then compile all routes
def self.prepare
@@routes = Array.new
@@compiled_statement = String.new
yield self
compile_router
end
+ # init @sections for route segment recognition
def initialize
@sections = Hash.new
end
+ # all defined routes in their raw form.
def routes
@@routes
end
+ # the final compiled lambda that gets used
+ # as the body of the route_request method.
def compiled_statement
@@compiled_statement
end
+ # add a route to be compiled
def self.add(*route)
@@routes << [route[0], (route[1] || {})]
end
+ # build up a string that defines a lambda
+ # that does a case statement on the PATH_INFO
+ # against each of the compiled routes in turn.
+ # first route that matches wins.
def self.compile_router
router_lambda = @@routes.inject("lambda{|path| \n case path\n") { |m,r|
m << compile(r)
} <<" else\n return {:controller=>'Noroutefound', :action=>'noroute'}\n end\n}"
@@compiled_statement = router_lambda
define_method(:route_request, &eval(router_lambda))
end
+ # compile each individual route into a when /.../
+ # component of the case statement. Takes /:sections
+ # if the route def that start with : and turns them
+ # into placeholders for whatever urls match against
+ # the route in question. Special case for the default
+ # /:controller/:action/:id route.
def self.compile(route)
raise ArgumentError unless String === route[0]
if route[0] == '/:controller/:action/:id'
return ' when /\A\/([^\/;.,?]+)(?:\/?\Z|\/([^\/;.,?]+)\/?)(?:\/?\Z|\/([^\/;.,?]+)\/?)\Z/
@sections[:controller] = $1