Module: GermanNumbers::StateMachine

Included in:
Parser::Parser, Parser::SmallNumberParser, Parser::StackMachine
Defined in:
lib/german_numbers/state_machine.rb

Defined Under Namespace

Classes: Machine, State, StateError

Instance Method Summary collapse

Instance Method Details

#state_machine_for(field, &block) ⇒ Object

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/german_numbers/state_machine.rb', line 60

def state_machine_for(field, &block)
  m = Machine.new
  m.instance_eval(&block)
  var_name = "@#{field}_state"
  set_name = "#{field}_state="
  history_name = "@#{field}_state_history"

  define_method("#{field}_state") do
    instance_variable_get(var_name)
  end

  define_method(set_name) do |ns|
    state = instance_variable_get(var_name)
    raise StateError, "#{ns} is not possible state after #{state}" unless m.transitions[state].include?(ns)
    if instance_variable_get(history_name).include?(ns) && m.states[ns].unique?
      raise StateError, "#{ns} is a unique state and has already been taken"
    end
    instance_variable_get(history_name) << ns
    instance_variable_set(var_name, ns)
  end

  define_method("initialize_#{field}") do |initial|
    m.validate_state!(initial)
    raise StateError, "#{initial} is not possible initial state" unless m.states[initial].can_be_initial?
    instance_variable_set(history_name, Set.new)
    instance_variable_set(var_name, initial)
  end

  define_method("final_#{field}_state?") do
    m.states[instance_variable_get(var_name)].final?
  end
end