class Alki::Dsl::Evaluator

Public Class Methods

evaluate(dsl, data={}, &blk) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 8
def self.evaluate(dsl, data={}, &blk)
  evaluator = new(dsl,data)
  evaluator.evaluate &blk
  evaluator.finish
end
new(dsl,data) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 14
def initialize(dsl,data)
  @inits = []
  @finishers = []
  @processors = []
  @dsls_seen = Set.new
  @data = data
  @mod = (data[:module] ||= Module.new)
  @dsl = dsl
  evaluator = self
  define_dsl_method :method_missing do |meth,*args,&b|
    evaluator.context.send meth, *args, &b
  end
  process_dsl @dsl
end

Public Instance Methods

build(data={},&blk) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 29
def build(data={},&blk)
  self.class.evaluate(@dsl,data,&blk)
end
context() click to toggle source
# File lib/alki/dsl/evaluator.rb, line 38
def context
  @context
end
define_dsl_method(name,&blk) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 76
def define_dsl_method(name,&blk)
  @mod.define_singleton_method name, &blk
end
evaluate(&blk) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 42
def evaluate(&blk)
  @context = @data[:context] || block_context(blk)
  @mod.class_exec &blk
end
finish() click to toggle source
# File lib/alki/dsl/evaluator.rb, line 80
def finish
  @finishers.reverse_each(&:call)
  clear_dsl_methods

  if @data.key? :result
    @data[:result]
  else
    @data
  end
end
process_dsl(dsl) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 33
def process_dsl(dsl)
  return unless @dsls_seen.add? dsl
  dsl.generate(self,@data)
end
require_dsl(source,dsl) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 47
def require_dsl(source,dsl)
  dsl_class = Alki.load(dsl)
  dsl_class.new(EvaluatorInstance.new(self,@data))
end
update(cbs) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 52
def update(cbs)
  after_requires = []
  if cbs[:requires]
    cbs[:requires].each do |(required_dsl,order)|
      case order
        when :before
          process_dsl Alki.load(required_dsl)
        when :after
          after_requires << [Alki.load(required_dsl)]
      end
    end
  end
  cbs[:init].call if cbs[:init]
  @finishers << cbs[:finish] if cbs[:finish]
  if cbs[:methods]
    cbs[:methods].each do |name, proc|
      define_dsl_method name, &proc
    end
  end
  after_requires.each do |process_args|
    process_dsl *process_args
  end
end

Private Instance Methods

block_context(blk) click to toggle source
# File lib/alki/dsl/evaluator.rb, line 99
def block_context(blk)
  b = blk.binding
  if b.respond_to? :receiver
    b.receiver
  else
    b.eval('self')
  end
end
clear_dsl_methods() click to toggle source
# File lib/alki/dsl/evaluator.rb, line 93
def clear_dsl_methods
  @mod.singleton_methods do |m|
    @mod.singleton_class.send :remove_method, m
  end
end