module StateGate::Builder::DynamicModuleCreationMethods

Description

Multiple private methods enabling StateGate::Builder to dynamically generate module, instance and class helper methods.

Private Instance Methods

_generate_method_redefine_detection() click to toggle source

Adds the hook method :method_added to the Klass, detecting any new method definitions for an attribute already defined as a StateGate.

If a matching method is discoverd, it adds a warning to logger, if defined, otherwise it outputs the warning to STDOUT via ‘puts`

method_name - the name of the newly defined method.

Note

This method is added last so it does not trigger when StateGate adds the attribute methods.

meta
  • loop though each state machine attribute.

    • does the new defined method use ‘attr’ or ‘attr=’?

      • if so then record an error logger if denied, othewise use ‘puts`

# File lib/state_gate/builder/dynamic_module_creation_methods.rb, line 68
def _generate_method_redefine_detection # rubocop:disable Metrics/MethodLength
  @klass.instance_eval(%(
    def method_added(method_name)
      stateables.keys.each do |attr_name|
        if method_name&.to_s == attr_name ||
           method_name&.to_s == "\#{attr_name}="

          msg  = "WARNING! \#{self.name}#\#{attr_name} is a defined StateGate and"
          msg += " redefining :\#{method_name} may cause conflict."

          logger ? logger.warn(msg) : puts("\n\n\#{msg}\n\n")
        end

        super(method_name)
      end
    end
  ), __FILE__, __LINE__ - 15)
end
_helper_methods_module() click to toggle source

Dynamically generated module to hold the StateGate helper methods. This keeps a clear distinction between the state machine helper methods and the klass’ own methods.

The module is named after the class and is created if needed, or reused if exisitng.

Note:

the module is named "<klass>::StateGate_HelperMethods"
# File lib/state_gate/builder/dynamic_module_creation_methods.rb, line 31
def _helper_methods_module
  @_helper_methods_module ||= begin
    if @klass.const_defined?('StateGate_HelperMethods')
      "#{@klass}::StateGate_HelperMethods".constantize
    else
      @klass.const_set('StateGate_HelperMethods', Module.new)
      mod = "#{@klass}::StateGate_HelperMethods".constantize
      @klass.include mod
      mod
    end
  end
end
add__instance__helper_method(method_name, file, line, method_body) click to toggle source

Add an instance helper method to the _helper_methods_module

method_name - a String name for the method, needed to check for conflicts file - a String file name for error reporting line - a String or Integer line number for error reporting method_body - a String to bhe evaluates in the module

# File lib/state_gate/builder/dynamic_module_creation_methods.rb, line 113
def add__instance__helper_method(method_name, file, line, method_body)
  detect_instance_method_conflict!(method_name)
  _helper_methods_module.module_eval(method_body, file, line)
end
add__klass__helper_method(method_name, file, line, method_body) click to toggle source

Add an Class helper method to the _helper_methods_module

method_name - a String name for the method, needed to check for conflicts file - a String file name for error reporting line - a String or Integer line number for error reporting method_body - a String to bhe evaluates in the module

# File lib/state_gate/builder/dynamic_module_creation_methods.rb, line 99
def add__klass__helper_method(method_name, file, line, method_body)
  detect_class_method_conflict!(method_name)
  @klass.instance_eval(method_body, file, line)
end