module TinyState class StateMachine attr_reader :attribute def initialize(attribute:) @attribute = attribute @states = Set.new @events = {} end def states = @states.to_a def events = @events.keys def inspect "#<#{self.class}:#{"%#016x" % (object_id << 1)} :#{attribute}, states: #{states}, events: #{events}>" end private def state(state) @states.merge([*state].map(&:to_sym)) end def event(name, klass) @events[name.to_sym] = klass end def register_events(klass) attribute = @attribute @events.each do |name, event_klass| klass.define_method(:"#{name}!") do event_klass.new(resource: self, attribute:).transition! end klass.define_method(:"#{name}?") do event_klass.new(resource: self, attribute:).transition? end end end end end