module Temple::Mixins::CompiledDispatcher

def call(exp)

def call(exp)
  compile(exp)
end

def compile(exp)

def compile(exp)
  dispatcher(exp)
end

def dispatched_methods

def dispatched_methods
  re = /^on(_[a-zA-Z0-9]+)*$/
  self.methods.map(&:to_s).select(&re.method(:=~))
end

def dispatcher(exp)

def dispatcher(exp)
  replace_dispatcher(exp)
end

def replace_dispatcher(exp)

def replace_dispatcher(exp)
  tree = DispatchNode.new
  dispatched_methods.each do |method|
    method.split('_'.freeze)[1..-1].inject(tree) {|node, type| node[type.to_sym] }.method = method
  end
  self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def dispatcher(exp)
      return replace_dispatcher(exp) if self.class != #{self.class}
      #{tree.compile.gsub("\n", "\n  ")}
    end
  RUBY
  dispatcher(exp)
end