97 lines
2.5 KiB
Ruby
97 lines
2.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'sinatra/base'
|
|
|
|
module Sinatra
|
|
# = Sinatra::Extension
|
|
#
|
|
# <tt>Sinatra::Extension</tt> is a mixin that provides some syntactic sugar
|
|
# for your extensions. It allows you to call almost any
|
|
# <tt>Sinatra::Base</tt> method directly inside your extension
|
|
# module. This means you can use +get+ to define a route, +before+
|
|
# to define a before filter, +set+ to define a setting and so on.
|
|
#
|
|
# Is important to be aware that this mixin remembers the method calls you
|
|
# make, and then, when your extension is registered, replays them on the
|
|
# Sinatra application that has been extended. In order to do that, it
|
|
# defines a <tt>registered</tt> method, so, if your extension defines one
|
|
# too, remember to call +super+.
|
|
#
|
|
# == Usage
|
|
#
|
|
# Just require the mixin and extend your extension with it:
|
|
#
|
|
# require 'sinatra/extension'
|
|
#
|
|
# module MyExtension
|
|
# extend Sinatra::Extension
|
|
#
|
|
# # set some settings for development
|
|
# configure :development do
|
|
# set :reload_stuff, true
|
|
# end
|
|
#
|
|
# # define a route
|
|
# get '/' do
|
|
# 'Hello World'
|
|
# end
|
|
#
|
|
# # The rest of your extension code goes here...
|
|
# end
|
|
#
|
|
# You can also create an extension with the +new+ method:
|
|
#
|
|
# MyExtension = Sinatra::Extension.new do
|
|
# # Your extension code goes here...
|
|
# end
|
|
#
|
|
# This is useful when you just want to pass a block to
|
|
# <tt>Sinatra::Base.register</tt>.
|
|
module Extension
|
|
def self.new(&block)
|
|
ext = Module.new.extend(self)
|
|
ext.class_eval(&block)
|
|
ext
|
|
end
|
|
|
|
def settings
|
|
self
|
|
end
|
|
|
|
def configure(*args, &block)
|
|
record(:configure, *args) { |c| c.instance_exec(c, &block) }
|
|
end
|
|
|
|
def registered(base = nil, &block)
|
|
base ? replay(base) : record(:class_eval, &block)
|
|
end
|
|
|
|
private
|
|
|
|
def record(method, *args, &block)
|
|
recorded_methods << [method, args, block]
|
|
end
|
|
|
|
def replay(object)
|
|
recorded_methods.each { |m, a, b| object.send(m, *a, &b) }
|
|
end
|
|
|
|
def recorded_methods
|
|
@recorded_methods ||= []
|
|
end
|
|
|
|
def method_missing(method, *args, &block)
|
|
return super unless Sinatra::Base.respond_to? method
|
|
|
|
record(method, *args, &block)
|
|
DontCall.new(method)
|
|
end
|
|
|
|
class DontCall < BasicObject
|
|
def initialize(method) @method = method end
|
|
def method_missing(*) raise "not supposed to use result of #{@method}!" end
|
|
def inspect; "#<#{self.class}: #{@method}>" end
|
|
end
|
|
end
|
|
end
|