Sha256: 3fc43c929af131c96250c845efdf5bfab36a35c723f80a69ee6ace27ad435fc4

Contents?: true

Size: 1.64 KB

Versions: 2

Compression:

Stored size: 1.64 KB

Contents

# frozen_string_literal: true

module Nina
  # Generates module that adds support for objects creation
  class Assembler
    # Adds ability to delegeate methods via method_missing
    module MethodMissingDelegation
      def method_missing(name, *attrs, &block)
        return super unless methods.detect { |m| m == :__predecessor }

        public_send(__predecessor).public_send(name, *attrs, &block)
      end

      def respond_to_missing?(method_name, _include_private = false)
        return super unless methods.detect { |m| m == :__predecessor }

        public_send(__predecessor).respond_to?(method_name)
      end
    end

    def self.def_accessor(accessor, on:, to:, delegate: false)
      on.define_singleton_method(:__predecessor) { accessor }
      on.define_singleton_method(accessor) { to }
      on.extend(MethodMissingDelegation) if delegate
    end

    def initialize(abstract_factory)
      @abstract_factory = abstract_factory
    end

    def inject(build_order, initialization = {}, callbacks: nil, delegate: false)
      build_order.each.with_index(-1).inject(nil) do |prev, (name, idx)|
        object = create_object(name, initialization)
        self.class.def_accessor(build_order[idx], on: object, to: prev, delegate: delegate) if prev
        callbacks.to_h.fetch(name, []).each { |c| c.call(object) } if callbacks
        object
      end
    end

    private

    def create_object(name, initialization = {})
      return @abstract_factory.send("#{name}_factory").create if initialization[name].nil?

      args, kwargs, block = initialization[name]
      @abstract_factory.send("#{name}_factory").create(*args, **kwargs, &block)
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
nina-0.1.2 lib/nina/assembler.rb
nina-0.1.1 lib/nina/assembler.rb