lib/symbiont/trigger.rb in symbiont-ruby-0.1.0 vs lib/symbiont/trigger.rb in symbiont-ruby-0.2.0
- old
+ new
@@ -5,11 +5,11 @@
# Delegation variations depends on the order of contexts.
#
# Trigger supports 3 contexts:
#
# * closure context;
-# * passed object's context;
+# * passed object's context (or context of the each passed object);
# * global ::Kernel context.
#
# If no context is able to respond to the required method - ContextNoMethodError exception is raised
# (ContextNoMethodError inherits from NoMethodError).
#
@@ -21,85 +21,86 @@
#
# @return [Array<Symbol>]
#
# @api public
# @since 0.1.0
- IOK = %i[__inner_context__ __outer_context__ __kernel_context__].freeze
+ IOK = %i[__inner_contexts__ __outer_context__ __kernel_context__].freeze
# Indicates the direction of context method resolving algorithm.
- # Direction: outer context => initial context => kernel context.
+ # Direction: outer context => initial contexts => kernel context.
#
# @return [Array<Symbol>]
#
# @api public
# @since 0.1.0
- OIK = %i[__outer_context__ __inner_context__ __kernel_context__].freeze
+ OIK = %i[__outer_context__ __inner_contexts__ __kernel_context__].freeze
# Indicates the direction of context method resolving algorithm.
- # Direction: outer context => kernel context => initial context.
+ # Direction: outer context => kernel context => initial contexts.
#
# @return [Array<Symbol>]
#
# @api public
# @since 0.1.0
- OKI = %i[__outer_context__ __kernel_context__ __inner_context__].freeze
+ OKI = %i[__outer_context__ __kernel_context__ __inner_contexts__].freeze
# Indicates the direction of context method resolving algorithm.
- # Direction: initial context => kernel context => outer context.
+ # Direction: initial contexts => kernel context => outer context.
#
# @return [Array<Symbol>]
#
# @api public
# @since 0.1.0
- IKO = %i[__inner_context__ __kernel_context__ __outer_context__].freeze
+ IKO = %i[__inner_contexts__ __kernel_context__ __outer_context__].freeze
# Indicates the direction of context method resolving algorithm.
- # Direction: kernel context => outer context => initial context.
+ # Direction: kernel context => outer context => initial contexts.
#
# @return [Array<Symbol>]
#
# @api public
# @since 0.1.0
- KOI = %i[__kernel_context__ __outer_context__ __inner_context__].freeze
+ KOI = %i[__kernel_context__ __outer_context__ __inner_contexts__].freeze
# Indicates the direction of context method resolving algorithm.
- # Direction: kernel context => initial context => outer context.
+ # Direction: kernel context => initial contexts => outer context.
#
# @return [Array<Symbol>]
#
# api public
# @since 0.1.0
- KIO = %i[__kernel_context__ __inner_context__ __outer_context__].freeze
+ KIO = %i[__kernel_context__ __inner_contexts__ __outer_context__].freeze
- # Is raised when closure (__outer_context__ instance attribute) isnt a Proc.
- #
- # @api public
- # @since 0.1.0
- IncompatibleclosureObjectError = ::Class.new(::ArgumentError)
-
# Is raised when chosen direction (__context_direction__ instance attribute) is not supported
# by a trigger. Supports only: OIK, OKI, IOK, IKO, KOI, KIO.
#
# @api public
# @since 0.1.0
IncompatibleContextDirectionError = ::Class.new(::ArgumentError)
+ # Is raised when closure isnt passed.
+ #
+ # @api public
+ # @since 0.2.0
+ UnprovidedClosureAttributeError = ::Class.new(::ArgumentError)
+
# Is raised when no one is able to respond to the required method.
#
# @see #__actual_context__
#
# @api public
# @since 0.1.0
ContextNoMethodError = ::Class.new(::NoMethodError)
- # Returns an object that should be used as the main context for
- # context method resolving algorithm.
+ # Returns a set of objects that should be used as the main context series for
+ # context method resolving algorithm. The order of object selection depends on
+ # their order in a set.
#
- # @return [Object]
+ # @return [Array<Object>]
#
# @since 0.1.0
- attr_reader :__inner_context__
+ attr_reader :__inner_contexts__
# Returns a binding object of corresponding closure (see __closure__).
# Used as an outer context for context method resolving algorithm.
#
# @return [Object]
@@ -123,38 +124,39 @@
#
# @api private
# @since 0.1.0
attr_reader :__closure__
- # Returns an array of symbols tha represents the direction of contexts.
+ # Returns an array of symbols that represents the direction of contexts.
# that represents an access method to each of them.
#
# @return [Array<Symbol>]
#
# @api private
# @since 0.1.0
attr_reader :__context_direction__
- # Instantiates trigger object with corresponding initial context, closure and context resolving
+ # Instantiates trigger object with corresponding initial contexts, closure and context resolving
# direction.
#
- # @param initial_context [Object]
- # Main context which should be used for instance_eval on.
+ # @param initial_contexts [Array<Object>]
+ # A set of main context objects which should be used for instance_eval on.
+ # An order of object selection depends on oredr which they are passed.
# @param closure [Proc]
# closure that will be executed in a set of contexts (initial => outer => kernel by default).
# An actual context (#__actual_context__) will be passed to a closure as an attribute.
- # @raise IncompatibleclosureObjectError
- # Raises when received closure attribte isnt a Proc.
+ # @raise UnprovidedClosureAttributeError
+ # Raises when closure attribte isnt passed.
# @raise IncompatibleContextDirectionError
# Is raised when chosen direction is not supported by a trigger.
# Supports only OIK, OKI, IOK, IKO, KOI, KIO (see corresponding constant value above).
#
# @api private
# @since 0.1.0
- def initialize(initial_context, closure, context_direction = IOK)
- unless closure.is_a?(::Proc)
- ::Kernel.raise(IncompatibleclosureObjectError, 'closure attribute should be a proc')
+ def initialize(*initial_contexts, context_direction: IOK, &closure)
+ unless ::Kernel.block_given?
+ ::Kernel.raise(UnprovidedClosureAttributeError, 'block attribute should be provided')
end
# rubocop:disable Layout/SpaceAroundKeyword
unless(context_direction == IOK || context_direction == OIK || context_direction == OKI ||
context_direction == IKO || context_direction == KOI || context_direction == KIO)
@@ -166,11 +168,11 @@
end
# rubocop:enable Layout/SpaceAroundKeyword
@__closure__ = closure
@__context_direction__ = context_direction
- @__inner_context__ = initial_context
+ @__inner_contexts__ = initial_contexts
@__outer_context__ = ::Kernel.eval('self', closure.binding)
@__kernel_context__ = ::Kernel
end
# Triggers a closure in multiple contexts.
@@ -184,29 +186,30 @@
def __evaluate__
instance_eval(&__closure__)
end
# Returns a collection of the all contexts sorted by chosen direction.
+ # Represents ordered single-dimentional array of objects (contexts).
#
# @return [Array<Object>]
#
# @see #__context_direction__
#
# @api private
# @since 0.1.0
def __directed_contexts__
- __context_direction__.map { |direction| __send__(direction) }
+ __context_direction__.map { |direction| __send__(direction) }.flatten
end
# Returns the first context that is able to respond to the required method.
# The context is chosen in the context direction order (see #__context_direction__).
# Raises NoMethodError excepition when no one of the contexts are able to respond to
# the required method.
# Basicaly, abstract implementation raises NoMethodError.
#
# @param method_name [Symbol,String] Method that a context should respond to.
- # @raise NoMethodError
+ # @raise ContextNoMethodError
#
# @see #__context_direction__
#
# @api private
# @since 0.1.0
@@ -217,11 +220,11 @@
# Delegates method invocation to the corresponding actual context.
#
# @param method_name [String,Symbol] Method name
# @param arguments [Mixed] Method arguments
# @param block [Proc] Block
- # @raise NoMethodError
+ # @raise ContextNoMethodError
# Is rased when no one of the contexts are able to respond tothe required method.
# @return void
#
# @see #__actual_context__
#
@@ -251,10 +254,10 @@
# :nocov:
# Returns a corresponding metehod object of the actual context.
#
# @param method_name [String,Symbol] Method name
- # @raise NoMethodError
+ # @raise ContextNoMethodError
# Is raised when no one of the contexts able to respond to the required method.
# @return [Method]
#
# @see #method_missing
# @see #respond_to_missing?