module Pakyow::Support::Definable::ClassMethods

Attributes

__inherited_state[R]
__state[R]

Public Instance Methods

define(&block) click to toggle source

Define state for the object.

# File lib/pakyow/support/definable.rb, line 140
def define(&block)
  class_exec(&block)
end
inherited(subclass) click to toggle source
Calls superclass method
# File lib/pakyow/support/definable.rb, line 70
def inherited(subclass)
  super

  subclass.instance_variable_set(:@__inherited_state, @__state.deep_dup)
  subclass.instance_variable_set(:@__state, @__state.each_with_object({}) { |(name, state_instance), state|
    state[name] = State.new(name, state_instance.object)
  })
end
stateful(name, object, &stateful_block) click to toggle source

Register a type of state that can be defined.

@param object

Can be a class or instance, but must respond to :make. The `make`
method should return the object to be "made" and accept a block
that should be evaluated in the context of the object.

  class Person
    # ...

    def make(name, dob, &block)
      person = self.class.new(name, dob)

      person.instance_eval(&block)
      person
    end

    def befriend(person)
      friends << person
    end
  end

  class Application
    include Pakyow::Support::Definable

    stateful :person, Person
  end

  john = Application.person 'John', Date.new(1988, 8, 13) do
  end

  Application.person 'Sofie', Date.new(2015, 9, 6) do
    befriend(john)
  end
# File lib/pakyow/support/definable.rb, line 114
def stateful(name, object, &stateful_block)
  name = name.to_sym
  @__state[name] = State.new(name, object)
  plural_name = Support.inflector.pluralize(name.to_s).to_sym

  within = if __object_name
    ObjectNamespace.new(*__object_name.namespace.parts.dup.concat([plural_name]))
  else
    self
  end

  method_body = Proc.new do |*args, priority: :default, **opts, &block|
    return @__state[name] if block.nil?

    stateful_block.call(args, opts) if stateful_block
    object.make(*args, within: within, **opts, &block).tap do |state|
      @__state[name].register(state, priority: priority)
    end
  end

  define_method name, &method_body
  define_singleton_method name, &method_body
end