module Pakyow::Support::Makeable

Attributes

__object_name[R]
__source_location[RW]

Public Class Methods

extended(base) click to toggle source
# File lib/pakyow/support/makeable.rb, line 11
def self.extended(base)
  # Mixin the `make` event for objects that are hookable.
  #
  if base.ancestors.include?(Hookable)
    base.events :make
  end
end

Private Class Methods

__object_name() click to toggle source
# File lib/pakyow/support/makeable.rb, line 93
def self.__object_name
  @__object_name
end

Public Instance Methods

make(object_name, within: nil, set_const: true, **kwargs, &block) click to toggle source
# File lib/pakyow/support/makeable.rb, line 22
def make(object_name, within: nil, set_const: true, **kwargs, &block)
  @__source_location = block&.source_location
  object_name = build_object_name(object_name, within: within)
  object = find_or_define_object(object_name, kwargs, set_const)

  local_eval_method = eval_method
  object.send(eval_method) do
    @__object_name = object_name
    send(local_eval_method, &block) if block_given?
  end

  if object.ancestors.include?(Hookable)
    object.call_hooks(:after, :make)
  end

  object
end

Private Instance Methods

build_object_name(object_name, within:) click to toggle source
# File lib/pakyow/support/makeable.rb, line 42
def build_object_name(object_name, within:)
  unless object_name.is_a?(ObjectName) || object_name.nil?
    namespace = if within && within.respond_to?(:__object_name)
      within.__object_name.namespace
    elsif within.is_a?(ObjectNamespace)
      within
    else
      ObjectNamespace.new
    end

    object_name_parts = object_name.to_s.gsub("-", "_").split("/").reject(&:empty?)
    class_name = object_name_parts.pop || :index

    object_name = Support::ObjectName.new(
      Support::ObjectNamespace.new(
        *(namespace.parts + object_name_parts)
      ), class_name
    )
  end

  object_name
end
define_object(kwargs) click to toggle source
# File lib/pakyow/support/makeable.rb, line 87
def define_object(kwargs)
  object = case self
  when Class
    Class.new(self)
  when Module
    Module.new do
      def self.__object_name
        @__object_name
      end
    end
  end

  object.send(eval_method) do
    kwargs.each do |arg, value|
      instance_variable_set(:"@#{arg}", value)
    end
  end

  object
end
eval_method() click to toggle source
# File lib/pakyow/support/makeable.rb, line 108
def eval_method
  case self
  when Class
    :class_exec
  when Module
    :module_exec
  end
end
find_or_define_object(object_name, kwargs, set_const) click to toggle source
# File lib/pakyow/support/makeable.rb, line 65
def find_or_define_object(object_name, kwargs, set_const)
  if object_name && ::Object.const_defined?(object_name.constant, false)
    existing_object = ::Object.const_get(object_name.constant)

    if type_of_self?(existing_object)
      existing_object
    else
      define_object(kwargs)
    end
  else
    define_object(kwargs).tap do |defined_object|
      if set_const
        ObjectMaker.define_const_for_object_with_name(defined_object, object_name)
      end
    end
  end
end
type_of_self?(object) click to toggle source
# File lib/pakyow/support/makeable.rb, line 83
def type_of_self?(object)
  object.ancestors.include?(ancestors[1])
end