module Roda::RodaPlugins::Base::ClassMethods
def build_rack_app
def build_rack_app if block = @route_block builder = Rack::Builder.new @middleware.each{|a, b| builder.use(*a, &b)} builder.run lambda{|env| allocate.call(env, &block)} @app = builder.to_app end end
def call(env)
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!
def clear_middleware! @middleware.clear build_rack_app end
def freeze
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 hash_matcher(key, &block)
def hash_matcher(key, &block) RodaPlugins.deprecate("Roda.hash_matcher is deprecated and will be removed in Roda 2. It has been moved to the hash_matcher plugin.") self::RodaRequest.send(:define_method, :"match_#{key}", &block) end
def inherited(subclass)
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 if v.is_a?(RodaDeprecateMutation) subclass.opts[k].extend(RodaDeprecateMutation) end 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 module_include(type, mod)
def module_include(type, mod) if type == :response klass = self::RodaResponse iv = :@response_module else klass = self::RodaRequest iv = :@request_module end if mod raise RodaError, "can't provide both argument and block to response_module" if block_given? klass.send(:include, mod) else if instance_variable_defined?(iv) mod = instance_variable_get(iv) else mod = instance_variable_set(iv, Module.new) klass.send(:include, mod) end mod.module_eval(&Proc.new) if block_given? end mod end
def plugin(plugin, *args, &block)
Roda.plugin PluginModule
which will be required and then used.
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 subclass 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) end
def request_module(mod = nil, &block)
def request_module(mod = nil, &block) RodaPlugins.deprecate("Roda.request_module is deprecated and will be removed in Roda 2. It has been moved to the module_include plugin.") module_include(:request, mod, &block) end
def response_module(mod = nil, &block)
def response_module(mod = nil, &block) RodaPlugins.deprecate("Roda.response_module is deprecated and will be removed in Roda 2. It has been moved to the module_include plugin.") module_include(:response, mod, &block) end
def route(&block)
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
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)
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