Sha256: 1eaff0bdad27c419852144e3e96faecc568ee6b6cd85fad0d9ecaa52262ca3dc

Contents?: true

Size: 1.95 KB

Versions: 8

Compression:

Stored size: 1.95 KB

Contents

module Scorpion
  # Builds an injectable constructor for a Scorpion::Object.
  class ObjectConstructor

    def initialize( base, arguments, &block )
      @base      = base
      @arguments = arguments
      @block     = block
    end

    def define
      @signature       = []
      @block_signature = []
      @body            = []

      define_dependencies
      build_body

      add_initialize_block
      add_super

      assemble
    end

    private
      attr_reader :base, :arguments, :block, :body

      def define_dependencies
        # Override the inherited injections cause we're about to define a new
        # initializer.
        base.instance_variable_set :@initializer_injections, AttributeSet.new

        arguments.each do |key,expectation|
          base.initializer_injections.define_attribute key, *Array( expectation )
          base.attr_dependency key, *Array( expectation )
        end
      end

      def build_body
        if arguments.present?
          body << "injections = dependencies.slice( :#{ arguments.keys.join(', :') } )"
          body << "inject_from( dependencies )"
        else
          body << "injections = {}"
        end
      end

      def add_super
        body << "super" if base.superclass < Scorpion::Object
      end

      def add_initialize_block
        if block
          base_name = base.name || base.object_id.to_s
          base_name = base_name.gsub /::/, '_'
          name = "__initialize_with_block_#{ base_name }"
          if block.arity != 0
            body << "#{ name }( *args, **injections, &block )"
          else
            body << "#{ name }"
          end
          base.send :define_method, :"#{ name }", &block
        end
      end

      def assemble
        source = %Q|def initialize( *args, **dependencies, &block )\n\t#{ body.join( "\n\t" ) }\nend|

        # puts base.name
        # puts source

        base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
#{ source }
        RUBY
      end
  end
end

Version data entries

8 entries across 8 versions & 1 rubygems

Version Path
scorpion-ioc-0.5.15 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.14 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.13 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.12 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.11 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.10 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.9 lib/scorpion/object_constructor.rb
scorpion-ioc-0.5.8 lib/scorpion/object_constructor.rb