lib/nina/builder.rb in nina-0.1.6 vs lib/nina/builder.rb in nina-0.2.0

- old
+ new

@@ -1,7 +1,10 @@ # frozen_string_literal: true +require 'nina/builder/initialization' +require 'nina/builder/callbacks' + # This should be a kind of factory that creates complex objects # from simple ones. It should use torirori to create objects. # It also enriches objects with some methods that make them more # like linked lists. module Nina @@ -9,25 +12,11 @@ class Builder attr_reader :name, :abstract_factory, :def_block, :callbacks # Definaes support methods and variables for concrete builder module ClassMethods - def build_order_list - @build_order_list ||= [] - end - - def build_order_list=(other) - @build_order_list = other.dup.freeze - end - - def inherited(subclass) - super - subclass.build_order_list = build_order_list.dup.freeze - end - def factory(name, *args, **kwargs, &block) - build_order_list << name super define_singleton_method(name) do |klass = nil, &definition| factories[__method__].subclass(produces: klass, &definition) end end @@ -36,54 +25,61 @@ def initialize(name, abstract_factory: nil, callbacks: nil, &def_block) @name = name @def_block = def_block @abstract_factory = abstract_factory.include(Toritori).extend(ClassMethods) @abstract_factory.class_eval(&def_block) if def_block - @abstract_factory.build_order_list.freeze - @assembler = Assembler.new(@abstract_factory, callbacks) - @assembler.add_observer(self) + @initialization = Builder::Initialization.new(self) + @callbacks = callbacks&.copy || Callbacks.new(@abstract_factory.factories.keys) @observers = [] end def add_observer(observer) @observers << observer end def copy - new_builder = self.class.new(name, abstract_factory: abstract_factory, callbacks: @assembler.callbacks) + new_builder = self.class.new(name, abstract_factory: abstract_factory, callbacks: @callbacks) @observers.each { |observer| new_builder.add_observer(observer) } new_builder end def with_callbacks(&block) - yield @assembler.callbacks if block + yield @callbacks if block copy end - def wrap(delegate: false, &block) - yield @assembler.initialization if block + def nest(delegate: false, &block) + yield @initialization if block - @assembler.inject(@abstract_factory.build_order_list, delegate: delegate) + Nina.link(@initialization.to_h, delegate: delegate) end - def nest(delegate: false, &block) - yield @assembler.initialization if block + def wrap(delegate: false, &block) + yield @initialization if block - @assembler.inject(@abstract_factory.build_order_list.reverse, delegate: delegate) + Nina.reverse_link(@initialization.to_h, delegate: delegate) end def subclass(&def_block) return unless def_block @abstract_factory = Class.new(abstract_factory) @abstract_factory.class_eval(&def_block) - @abstract_factory.build_order_list.freeze - @assembler = Assembler.new(@abstract_factory, @assembler.callbacks) - @assembler.add_observer(self) + @initialization = Builder::Initialization.new(self) + @callbacks = callbacks&.copy || Callbacks.new(@abstract_factory.build_order_list) end + private + + def callbacks_for(name) + return [] unless @callbacks + + @callbacks.to_h.fetch(name, []) + end + def update(name, object) + callbacks_for(name).each { |c| c.call(object) } @observers.each do |observer| observer.public_send(:"on_#{name}_created", object, @name) if observer.respond_to?(:"on_#{name}_created") end end end