module Tool::Decoration

Mixin for easy method decorations.

@example

class Frank
  extend Tool::Decoration
  def self.get(path, &block)
    decorate(block) do |method|
      puts "mapping GET #{path} to #{method}"
    end
  end
end

# Output:
#   mapping GET /hi to __generated1
#   mapping GET / to index
#   mapping GET /index.php to index
class MyApp < Frank
  get '/hi' do
    "Hello World"
  end

  get '/'; get '/index.php'
  def index
    "This is the index page."
  end
end

Public Instance Methods

decorate(block = nil, name: "generated", &callback) click to toggle source

Set up a decoration.

@param [Proc, UnboundMethod, nil] block used for defining a method right away @param [String, Symbol] name given to the generated method if block is given @yield callback called with method name once method is defined @yieldparam [Symbol] method name of the method that is to be decorated

# File lib/tool/decoration.rb, line 67
def decorate(block = nil, name: "generated", &callback)
  @decorations << callback

  if block
    alias_name = "__" << name.to_s.downcase.gsub(/[^a-z]+/, ?_) << ?1
    alias_name = alias_name.succ while respond_to? alias_name, true
    without_decorations { define_method(name, &block) }
    alias_method(alias_name, name)
    remove_method(name)
    private(alias_name)
  end
end
without_decorations() { || ... } click to toggle source

Runs a given block without applying decorations defined outside of the block. Decorations defined before the block will still be registered after the block.

@yield block to run without decorations

# File lib/tool/decoration.rb, line 84
def without_decorations
  @decorations.clear if was = @decorations.to_a.dup
  yield
ensure
  @decorations.replace(was) if was
end

Private Instance Methods

method_added(name) click to toggle source
Calls superclass method
# File lib/tool/decoration.rb, line 91
def method_added(name)
  @decorations.each { |d| d.call(name) }.clear
  super
end
setup_decorations() click to toggle source
# File lib/tool/decoration.rb, line 96
def setup_decorations
  @decorations = Tool::ThreadLocal.new([])
end