module Merb class RouteMatcher attr_accessor :sections SECTION_REGEX = /(?::([a-z]+))/ unless defined?SECTION_REGEX def self.prepare @@routes = Array.new @@compiled_statement = String.new yield self compile_router end def initialize @sections = Hash.new end def routes @@routes end def compiled_statement @@compiled_statement end def self.add(*route) @@routes << route end def self.compile_router router_lambda = @@routes.inject('lambda{|path| ') { |m,r| m << compile(r) } << "\n return {:class=>'NoRouteFound', :method=>'noroute'}\n}" @@compiled_statement = router_lambda define_method(:route_request, &eval(router_lambda)) end def self.compile(route) raise ArgumentError unless String === route[0] code, count = '', 0 while route[0] =~ SECTION_REGEX route[0] = route[0].dup name = $1 count += 1 route[0].sub!(SECTION_REGEX, '(.+)') code << " @sections[:#{name}] = $#{count}\n" end condition = " if Regexp.new('#{route[0]}') =~ path" statement = "\n#{condition}\n#{code}" statement << " return #{route[1].inspect}.merge(@sections)\n end\n" statement end end end =begin if __FILE__ == $0 Merb::RouteMatcher.prepare do |r| r.add '/foo/:bar/baz/:id', :class => 'Test', :method => 'foo' r.add '/hey/:there/you/:guys', :class => 'Test', :method => 'hello' r.add '/these/:routes/are/:sweet', :class => 'Upload', :method => 'start' r.add '/h/:a/b/:c/d/:f/g/:id', :class => 'Test' r.add '/:class/:method/:id', {} r.add '/:class/:method', {} end routes = Merb::RouteMatcher.new puts routes.compiled_statement p routes.route_request( "/foo/234/baz/dsdsd") routes = Merb::RouteMatcher.new p routes.route_request( "/hey/jon/you/girls") routes = Merb::RouteMatcher.new p routes.route_request( "/upload/test/12") routes = Merb::RouteMatcher.new p routes.route_request( "/these/234/are/yup") routes = Merb::RouteMatcher.new p routes.route_request( '/h/12/b/red/d/blue/g/12') routes = Merb::RouteMatcher.new p routes.route_request( '/hdsfvsdfsdfdsf') p routes.routes end =end