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