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.