Write Software, Well

Step 1: Refactor the Router

Let's make a few small changes to the router, so it looks like this.

# weby/router.rb

require 'singleton'

class Router
include Singleton # 1

attr_reader :routes

class << self
def draw(&blk) # 2
Router.instance.instance_exec(&blk) # 3
end
end

def initialize
@routes = {}
end

def get(path, &blk)
@routes[path] = blk
end

def build_response(path)
handler = @routes[path] || ->{ "no route found for #{path}" }
handler.call
end
end

Three important things to note:

  1. I've made the Router class a Singleton so we always have a single instance to work with. Refer the Singleton documentation to learn more about how it works. In short, the Singleton pattern ensures that a class has only one globally accessible instance.
  2. Added a draw method on the Router class so we could call it as Router.draw. This is a syntactic sugar to mimic Rails.
  3. The draw method accepts a block and executes that block in the context of the instance of the Router class. This is exactly what the Rails Router does. Refer to the instance_exec documentation to learn how it works.

Now, let's put this Router class to good use by creating the routes in a separate file.