lib/blueprints/root_namespace.rb in blueprints-0.8.2 vs lib/blueprints/root_namespace.rb in blueprints-0.9.0

- old
+ new

@@ -1,69 +1,68 @@ + module Blueprints # Defines a root namespace that is used when no other namespace is. Apart from functionality in namespace it also allows # building blueprints/namespaces by name. Is also used for copying instance variables between blueprints/contexts/global # context. class RootNamespace < Namespace - attr_reader :context, :executed_blueprints + # Lists of executed blueprints (to prevent executing twice). Cleared before each test. + attr_reader :executed_blueprints + # Context that blueprints/namespaces are built against. Reset before each test. + attr_writer :eval_context + # Initialized new root context. def initialize @executed_blueprints = @global_executed_blueprints = [] @auto_iv_list = Set.new - super '' + super '', Context.new end - # Loads all instance variables from global context to current one. + # Loads all instance variables from global context to current one. Creates new eval context. def setup + @eval_context = EvalContext.new (@executed_blueprints - @global_executed_blueprints).each(&:undo!) @executed_blueprints = @global_executed_blueprints.clone - @context = Blueprints::Context.new if Blueprints.config.transactions - Marshal.load(@global_variables).each { |name, value| @context.instance_variable_set(name, value) } + Marshal.load(@global_variables).each { |name, value| eval_context.instance_variable_set(name, value) } else build(Blueprints.config.prebuild) end end - # Copies all instance variables from current context to another one. - def copy_ivars(to) - @context.instance_variables.each do |iv| - to.instance_variable_set(iv, @context.instance_variable_get(iv)) - end - end - # Sets up global context and executes prebuilt blueprints against it. + # @param [Array<Symbol, String>] blueprints Names of blueprints that are prebuilt. def prebuild(blueprints) - @context = Blueprints::Context.new build(blueprints) if blueprints @global_executed_blueprints = @executed_blueprints - @global_variables = Marshal.dump(@context.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = @context.instance_variable_get(iv) }) + @global_variables = Marshal.dump(eval_context.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = eval_context.instance_variable_get(iv) }) end # Builds blueprints that are passed against current context. Copies instance variables to context given if one is given. - def build(names, context = nil, build_once = true) + # @param [Array<Symbol, String>] names List of blueprints/namespaces to build. + # @param current_context Object to copy instance variables from eval context after building to. + # @param build_once (see Buildable.build) + # @return Result of last blueprint/namespace. + def build(names, current_context = nil, build_once = true) names = [names] unless names.is_a?(Array) result = names.inject(nil) do |result, member| if member.is_a?(Hash) - member.map { |name, options| self[name].build(build_once, options) }.last + member.map { |name, options| self[name].build(eval_context, build_once, options) }.last else - self[member].build(build_once) + self[member].build(eval_context, build_once) end end - copy_ivars(context) if context + eval_context.copy_instance_variables(current_context) if current_context result end - # Sets instance variable in current context to passed value. If instance variable with same name already exists, it - # is set only if it was set using this same method - def add_variable(name, value) - if not @context.instance_variable_defined?(name) or @auto_iv_list.include?(name) - @auto_iv_list << name - @context.instance_variable_set(name, value) - end + # Return current eval context or creates a new one. + # @return [Blueprints::EvalContext] Eval context to be used to build blueprints. + def eval_context + @eval_context ||= EvalContext.new end @@root = RootNamespace.new end end