<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>.gitignore</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -7,17 +7,26 @@ module Rack
     autoload :Condition, 'rack/router/condition'
     autoload :Builder,   'rack/router/builders'
     
+    attr_reader :routes
+    attr_reader :named_routes
+    
     def initialize(app, options = {}, &amp;block)
-      @app     = app || lambda { |env| [ 404, { 'Content-Type' =&gt; 'text/html' }, &quot;Not Found&quot; ] }
-      @builder = options.delete(:builder) || Builder::Simple
-      @routes  = @builder.run(options, &amp;block)
+      @app          = app || fallback
+      @builder      = options.delete(:builder) || Builder::Simple
+      @routes       = @builder.run(options, &amp;block)
+      @named_routes = {}
       
-      @routes.each { |route| route.compile }
+      @routes.each do |route|
+        route.compile
+        @named_routes[route.name] = route if route.name
+      end
     end
     
     def call(env)
+      request  = Rack::Request.new(env)
+      
       for route in @routes
-        if args = route.match(env)
+        if args = route.match(request)
           # The routing args are destructively merged into the rack
           # environment so that they can be used by any application
           # called by the router or any app downstream.
@@ -34,8 +43,20 @@ module Rack
       @app.call(env)
     end
     
+    def url(name, params = {})
+      unless route = named_routes[name]
+        raise ArgumentError, &quot;Cannot find route named '#{name}'&quot;
+      end
+      
+      route.generate(params)
+    end
+    
     def end_points
       @end_points ||= @routes.map { |r| r.app }.uniq
     end
+    
+    def fallback
+      lambda { |env| [ 404, { 'Content-Type' =&gt; 'text/html' }, &quot;Not Found&quot; ] }
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>lib/rack/router.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,10 @@
 class Rack::Router::Builder
   class Simple
     
+    # Route format:
+    # ---
+    # :scheme :// :subdomain . :domain / :path
+    # { :scheme =&gt; :scheme, :host =&gt; :host, :subdomain =&gt; :subdomain, :domain =&gt; :domain, :path =&gt; :path }
     def self.run(options = {})
       builder = new
       yield builder
@@ -20,7 +24,10 @@ class Rack::Router::Builder
       conditions[:path_info]      = path if path
       conditions[:request_method] = upcase_method(args.last) if args.last
       
-      @routes &lt;&lt; Rack::Router::Route.new(options[:to], conditions.reject { |k,v| k == :id }, conditions.dup, options[:with] || {})
+      route = Rack::Router::Route.new(options[:to], conditions.reject { |k,v| k == :id }, conditions.dup, options[:with] || {})
+      route.name = options[:name].to_sym if options[:name]
+      
+      @routes &lt;&lt; route
     end
     
   private</diff>
      <filename>lib/rack/router/builders/simple.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,6 +13,8 @@ class Rack::Router
       @captures   = {}
       @conditions = conditions
       
+      @conditions.default = /#{SEGMENT_CHARACTERS}+/
+      
       case pattern
       when String
         @segments = parse_segments_with_optionals(pattern.dup)
@@ -33,6 +35,10 @@ class Rack::Router
       end
     end
     
+    def generate(params)
+      generate_from_segments(@segments, params) or raise ArgumentError, &quot;Condition cannot be generated with #{params.inspect}&quot;
+    end
+    
     def inspect
       @pattern.inspect
     end
@@ -86,7 +92,7 @@ class Rack::Router
         when String
           Regexp.escape(segment)
         when Symbol
-          condition = @conditions[segment] || /#{SEGMENT_CHARACTERS}+/
+          condition = @conditions[segment]
           condition = Regexp.escape(condition) unless condition.is_a?(Regexp)
           &quot;(#{condition})&quot;
         when Array
@@ -113,6 +119,20 @@ class Rack::Router
       end
     end
     
+    def generate_from_segments(segments, params)
+      segments.map do |segment|
+        case segment
+        when String
+          segment
+        when Symbol
+          return unless params[segment] &amp;&amp; params[segment].to_s =~ @conditions[segment]
+          params[segment]
+        when Array
+          generate_from_segments(segment, params) || &quot;&quot;
+        end
+      end.join
+    end
+    
     # ==== UTILITIES ====
     
     def convert_to_regexp(item)</diff>
      <filename>lib/rack/router/condition.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,8 +23,7 @@ class Rack::Router
       @keys ||= [@request_conditions.map { |c| c.captures }, @params.keys].flatten.uniq
     end
     
-    def match(env)
-      request  = Rack::Request.new(env)
+    def match(request)
       params = @params.dup
       
       return unless request_conditions.all? do |method_name, condition|
@@ -35,5 +34,9 @@ class Rack::Router
       params
     end
     
+    def generate(params)
+      @request_conditions[:path_info].generate(params)
+    end
+    
   end
 end
\ No newline at end of file</diff>
      <filename>lib/rack/router/route.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,52 @@ describe &quot;When generating URLs&quot; do
       end
     end
     
+    it &quot;generates with no parameters&quot; do
+      @app.url(:simple).should == &quot;/hello/world&quot;
+    end
+
+    it &quot;appends any parameters to the query string&quot; do
+      pending do
+        @app.url(:simple, :foo =&gt; &quot;bar&quot;).should == &quot;/hello/world?foo=bar&quot;
+      end
+    end
+    
+  end
+  
+  describe &quot;a named route with a variable and no conditions&quot; do
+    
+    before(:each) do
+      prepare do |r|
+        r.map &quot;/:account/welcome&quot;, :to =&gt; FooApp, :name =&gt; :welcome
+      end
+    end
+
+    it &quot;generates a URL with a paramter passed for the variable&quot; do
+      @app.url(:welcome, :account =&gt; &quot;walruses&quot;).should == &quot;/walruses/welcome&quot;
+    end
+
+    it &quot;appends any extra parameters to the query string&quot; do
+      pending do
+        @app.url(:welcome, :account =&gt; &quot;seagulls&quot;, :like_walruses =&gt; &quot;true&quot;).should == &quot;/seagulls/welcome?like_walruses=true&quot;
+      end
+    end
+
+    it &quot;raises an error if no parameters are passed&quot; do
+      lambda { @app.url(:welcome) }.should raise_error(ArgumentError)
+    end
+    
+    it &quot;raises an error if a nil parameter is passed&quot; do
+      lambda { @app.url(:welcome, :account =&gt; nil) }.should raise_error(ArgumentError)
+    end
+    
+    it &quot;raises an error if a blank parameter is passed&quot; do
+      lambda { @app.url(:welcome, :account =&gt; &quot;&quot;) }.should raise_error(ArgumentError)
+    end
+
+    it &quot;raises an error if parameters are passed without :account&quot; do
+      lambda { @app.url(:welcome, :foo =&gt; &quot;bar&quot;) }.should raise_error(ArgumentError)
+    end
+    
   end
   
 end
\ No newline at end of file</diff>
      <filename>spec/generation/string_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -68,7 +68,11 @@ Object.instance_eval do
       Object.instance_eval %{
         class ::#{name}
           def self.call(env)
-            [ 200, { &quot;Content-Type&quot; =&gt; 'text/yaml' }, YAML.dump(env.merge(&quot;app&quot; =&gt; &quot;#{name}&quot;)) ]
+            resp = {}
+            resp['rack.routing_args'] = env['rack.routing_args']
+            resp['app'] = '#{name}'
+            
+            [ 200, { &quot;Content-Type&quot; =&gt; 'text/yaml' }, YAML.dump(resp) ]
           end
         end
         ::#{name}</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1a7b7d670d6ecf5975fb312877909c57e501f689</id>
    </parent>
  </parents>
  <author>
    <name>Carl Lerche</name>
    <email>carllerche@mac.com</email>
  </author>
  <url>http://github.com/carllerche/rack-router/commit/10ca081cd90bf05b1b552eaaf31b49496756af87</url>
  <id>10ca081cd90bf05b1b552eaaf31b49496756af87</id>
  <committed-date>2009-03-26T13:54:26-07:00</committed-date>
  <authored-date>2009-03-26T13:54:26-07:00</authored-date>
  <message>Started writing route generation</message>
  <tree>20cd73cfa5abaf83f941760db242cf71e65be8bc</tree>
  <committer>
    <name>Carl Lerche</name>
    <email>carllerche@mac.com</email>
  </committer>
</commit>
