class Decorator

Base decorator class

Attributes

decorated_class[RW]

@!attribute [a] decorated_class The class being decorated

@return [Class]

@api private

decorated_method[RW]

@!attribute [a] decorated_class The method being decorated

@return [Symbol]

@api private

Private Instance Methods

build_next_caller(this, chain, *args, &block) click to toggle source

Produces a proc that invokes the next caller

@param this [Instance] the instance of the object with the wrapper method @param chain [Array<Decorator>] the remaining decorators to be called @param args [Array<Object>] the arguments to pass to the wrapper method @param block [Proc] the block to pass to the wrapped method

@return [Proc]

@api private

# File lib/decorator.rb, line 60
def build_next_caller(this, chain, *args, &block)
  next_caller = chain.shift

  if next_caller.nil?
    proc { decorated_method.bind(this).call(*args, &block) }
  else
    proc { next_caller.__send__(:call, this, chain, *args, &block) }
  end
end
call(this, chain, *args, &block) click to toggle source

The hook to call chained decorations

@param this [Instance] the instance of the object with the wrapper method @param chain [Array<Decorator>] the remaining decorators to be called @param args [Array<Object>] the arguments to pass to the wrapper method @param block [Proc] the block to pass to the wrapped method

@return [Object] the return value of the next_caller

@api private

# File lib/decorator.rb, line 41
def call(this, chain, *args, &block)
  execute_before_methods
  ret = execute_around_methods(build_next_caller(this, chain, *args, &block))
  execute_after_methods

  ret
end
execute_after_methods() click to toggle source

Executes the after methods

@return [Void]

@api private

# File lib/decorator.rb, line 106
def execute_after_methods
  self.class.__send__(:after_method)&.each { |method_name| __send__(method_name) }
end
execute_around_methods(next_caller) click to toggle source

Executes the around methods

@param next_caller [Proc] the proc to execute the next caller

@return [Object] the result of the next_caller

@api private

# File lib/decorator.rb, line 88
def execute_around_methods(next_caller)
  arounds = self.class.__send__(:around_method)
  if arounds.nil?
    ret = next_caller.call
  else
    ret = nil
    arounds.each { |method_name| ret = __send__(method_name) { next_caller.call } }
  end

  ret
end
execute_before_methods() click to toggle source

Executes the before methods

@return [Void]

@api private

# File lib/decorator.rb, line 76
def execute_before_methods
  self.class.__send__(:before_method)&.each { |method_name| __send__(method_name) }
end