module Roda::RodaPlugins::Base::ClassMethods

def build_rack_app

Build the rack app to use
def build_rack_app
  if block = @route_block
    app = lambda{|env| new(env).call(&block)}
    @middleware.reverse_each do |args, bl|
      mid, *args = args
      app = mid.new(app, *args, &bl)
      app.freeze if opts[:freeze_middleware]
    end
    @app = app
  end
end

def call(env)

access to the underlying rack app.
However, for performance, it's better to use #app to get direct
This allows the class itself to be used as a rack application.
Call the internal rack application with the given environment.
def call(env)
  app.call(env)
end

def clear_middleware!

Clear the middleware stack
def clear_middleware!
  @middleware.clear
  build_rack_app
end

def expand_path(path, root=opts[:root])

Expand the given path, using the root argument as the base directory.
def expand_path(path, root=opts[:root])
  ::File.expand_path(path, root)
end

def freeze

it would cause some plugins to break.
Note that freezing the class prevents you from subclassing it, mostly because

be raised if you try to modify the internal state after calling this.
internal state at runtime anyway, but this makes sure an exception will
It's optional to call this method, as nothing should be modifying the
Freeze the internal state of the class, to avoid thread safety issues at runtime.
def freeze
  @opts.freeze
  @middleware.freeze
  super
end

def inherited(subclass)

and setup the request and response subclasses.
When inheriting Roda, copy the shared data into the subclass,
def inherited(subclass)
  raise RodaError, "Cannot subclass a frozen Roda class" if frozen?
  super
  subclass.instance_variable_set(:@inherit_middleware, @inherit_middleware)
  subclass.instance_variable_set(:@middleware, @inherit_middleware ? @middleware.dup : [])
  subclass.instance_variable_set(:@opts, opts.dup)
  subclass.opts.to_a.each do |k,v|
    if (v.is_a?(Array) || v.is_a?(Hash)) && !v.frozen?
      subclass.opts[k] = v.dup
    end
  end
  subclass.instance_variable_set(:@route_block, @route_block)
  subclass.send(:build_rack_app)
  
  request_class = Class.new(self::RodaRequest)
  request_class.roda_class = subclass
  request_class.match_pattern_cache = thread_safe_cache
  subclass.const_set(:RodaRequest, request_class)
  response_class = Class.new(self::RodaResponse)
  response_class.roda_class = subclass
  subclass.const_set(:RodaResponse, response_class)
end

def plugin(plugin, *args, &block)

Roda.plugin :csrf
Roda.plugin PluginModule

which will be required and then used. Returns nil.
which is used directly, or a symbol represented a registered plugin
Load a new plugin into the current class. A plugin can be a module
def plugin(plugin, *args, &block)
  raise RodaError, "Cannot add a plugin to a frozen Roda class" if frozen?
  plugin = RodaPlugins.load_plugin(plugin) if plugin.is_a?(Symbol)
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
  self::RodaRequest.send(:include, plugin::RequestMethods) if defined?(plugin::RequestMethods)
  self::RodaRequest.extend(plugin::RequestClassMethods) if defined?(plugin::RequestClassMethods)
  self::RodaResponse.send(:include, plugin::ResponseMethods) if defined?(plugin::ResponseMethods)
  self::RodaResponse.extend(plugin::ResponseClassMethods) if defined?(plugin::ResponseClassMethods)
  plugin.configure(self, *args, &block) if plugin.respond_to?(:configure)
  nil
end

def route(&block)

times will overwrite the previous routing.
This should only be called once per class, and if called multiple

end
end
"Root"
r.root do
Roda.route do |r|

argument should be named +r+. Example:
a block, which is yielded the request. By convention, the block
underlying rack application using the stored middleware. Requires
Setup routing tree for the current Roda application, and build the
def route(&block)
  @route_block = block
  build_rack_app
end

def thread_safe_cache

easily overridden for alternative implementations.
A new thread safe cache instance. This is a method so it can be
def thread_safe_cache
  RodaCache.new
end

def use(*args, &block)

Roda.use Rack::Session::Cookie, :secret=>ENV['secret']

called before calling #route to have an effect. Example:
Add a middleware to use for the rack application. Must be
def use(*args, &block)
  @middleware << [args, block].freeze
  build_rack_app
end