Module: StepSequencer

Defined in:
lib/step_sequencer.rb,
lib/step_sequencer/version.rb

Defined Under Namespace

Modules: ClassMethods Classes: NoHaltHandlerConfigured

Constant Summary collapse

VERSION =
'0.2.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#haltedObject

Returns the value of attribute halted.



31
32
33
# File 'lib/step_sequencer.rb', line 31

def halted
  @halted
end

#halted_reasonObject

Returns the value of attribute halted_reason.



31
32
33
# File 'lib/step_sequencer.rb', line 31

def halted_reason
  @halted_reason
end

#halted_stepObject

Returns the value of attribute halted_step.



31
32
33
# File 'lib/step_sequencer.rb', line 31

def halted_step
  @halted_step
end

Class Method Details

.included(base) ⇒ Object



6
7
8
# File 'lib/step_sequencer.rb', line 6

def self.included(base)
  base.extend ClassMethods
end

Instance Method Details

#halt_sequence!(reason) ⇒ Object



33
34
35
36
# File 'lib/step_sequencer.rb', line 33

def halt_sequence!(reason)
  @halted        = true
  @halted_reason = reason
end

#start_sequence(initial_value = nil) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/step_sequencer.rb', line 38

def start_sequence(initial_value = nil)
  accumulator = initial_value
  steps_list = [*self.class.steps, :terminus_of_sequence]
  steps_list.each_with_index do |step_name, idx|
    if @halted
      @halted_step = steps_list[idx - 1] # The step before the current one is the one that caused the halt
      # Yield to the on_halt block with the step and reason
      return self.class.halt_handler.call(@halted_step, @halted_reason)

    end
    next if step_name == :terminus_of_sequence

    # Verify if the step method exists
    unless respond_to?(step_name)
      raise NoMethodError, "Method `#{step_name}` is not defined for #{self.class.name} used in steps"
    end

    step_method = method(step_name)
    accumulator = step_method.arity.zero? ? step_method.call : step_method.call(accumulator)
  rescue NoMethodError => e
    raise # Re-raise NoMethodError to avoid catching it with StandardError
  rescue StandardError => e
    halt_sequence!(e.message) # Call halt_sequence! with the exception message
    retry # Restart the loop to handle the halt
  end

  accumulator
end