Refactoring: Replaced custom implementation with Ruby core Delegator classes.

This commit is contained in:
Thorsten Eckel 2017-09-01 14:28:06 +02:00
parent b23f0d21d5
commit e47b366d6a
4 changed files with 36 additions and 89 deletions

View file

@ -1,43 +0,0 @@
module Mixin
# This modules enables to redirect all calls to methods that are
# not defined to the declared instance variable. This comes handy
# when you wan't extend a Ruby core class like Hash.
# To inherit directly from such classes is a bad idea and should be avoided.
# This way allows it indirectly.
module InstanceWrapper
module ClassMethods
# Creates the class macro `wrap` that activates
# the wrapping for the given instance variable name.
#
# @param [Symbol] variable the name of the instance variable to wrap around
#
# @example
# wrap :@some_hash
#
# @return [nil]
def wrap(variable)
define_method(:instance) do
instance_variable_get(variable)
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
private
def method_missing(method, *args, &block)
if instance.respond_to?(method)
instance.send(method, *args, &block)
else
super
end
end
def respond_to_missing?(method_sym, include_all)
instance.respond_to?(method_sym, include_all)
end
end
end

View file

@ -1,11 +1,9 @@
require 'mixin/instance_wrapper'
require 'sequencer/units/attribute'
require 'sequencer/units/attributes'
class Sequencer
class Units
class Units < SimpleDelegator
include ::Enumerable
include ::Mixin::InstanceWrapper
wrap :@units
# Initializes a new Sequencer::Units instance with the given Units Array.
#
@ -14,7 +12,7 @@ class Sequencer
# @example
# Sequencer::Units.new('Example::Unit', 'Sequencer::Unit::Second::Unit')
def initialize(*units)
@units = units
super(units)
end
# Required #each implementation for ::Enumerable functionality. Constantizes
@ -27,7 +25,7 @@ class Sequencer
#
# @return [nil]
def each
@units.each do |unit|
__getobj__.each do |unit|
yield constantize(unit)
end
end
@ -58,7 +56,7 @@ class Sequencer
#
# @return [Object] the Unit class for the requested index
def [](index)
constantize(@units[index])
constantize(__getobj__[index])
end
private

View file

@ -1,5 +1,5 @@
class Sequencer
class Units
class Units < SimpleDelegator
class Attribute
attr_accessor :from, :to

View file

@ -1,28 +1,15 @@
require 'mixin/instance_wrapper'
class Sequencer
class Units
class Attributes
include ::Mixin::InstanceWrapper
class Units < SimpleDelegator
wrap :@attributes
# Initializes the lifespan store for the attributes
# of the given Units declarations.
#
# @param [Array<Hash{Symbol => Array<:Symbol>}>] declarations the list of Unit declarations.
#
# @example
# declarations = [{uses: [:attribute1, ...], provides: [:result], ...}]
# attributes = Sequencer::Units::Attributes(declarations)
#
# @return [nil]
def initialize(declarations)
@declarations = declarations
initialize_attributes
initialize_lifespan
end
# Initializes the lifespan store for the attributes
# of the given Units declarations.
#
# @param [Array<Hash{Symbol => Array<:Symbol>}>] declarations the list of Unit declarations.
#
# @example
# declarations = [{uses: [:attribute1, ...], provides: [:result], ...}]
# attributes = Sequencer::Units::Attributes(declarations)
class Attributes < Delegator
# Lists all `provides` declarations of the Units the instance was initialized with.
#
@ -61,24 +48,29 @@ class Sequencer
key?(attribute)
end
private
def initialize_attributes
@attributes = Hash.new do |hash, key|
hash[key] = Sequencer::Units::Attribute.new
end
def __getobj__
@attributes
end
def initialize_lifespan
@declarations.each_with_index do |unit, index|
unit[:uses].try(:each) do |attribute|
self[attribute].to = index
def __setobj__(declarations)
@attributes ||= begin
attributes = Hash.new do |hash, key|
hash[key] = Sequencer::Units::Attribute.new
end
unit[:provides].try(:each) do |attribute|
next if self[attribute].will_be_provided?
self[attribute].from = index
attributes.tap do |result|
declarations.each_with_index do |unit, index|
unit[:uses].try(:each) do |attribute|
result[attribute].to = index
end
unit[:provides].try(:each) do |attribute|
next if result[attribute].will_be_provided?
result[attribute].from = index
end
end
end
end
end