Sha256: 341da3e7a74f9afd37ce02d6eb1c3df9411b8c7387644d758aecdcc7ed3c4611

Contents?: true

Size: 1.84 KB

Versions: 1

Compression:

Stored size: 1.84 KB

Contents

module StatefulEnum
  class Machine
    def initialize(model, column, states, &block)
      @model, @column, @states, @event_names = model, column, states, []

      # undef non-verb methods e.g. Model#active!
      states.each_key do |state|
        @model.send :undef_method, "#{state}!"
      end

      instance_eval(&block) if block
    end

    def event(name, &block)
      raise "event: :#{name} has already been defined." if @event_names.include? name
      Event.new @model, @column, @states, name, &block
      @event_names << name
    end

    class Event
      def initialize(model, column, states, name, &block)
        @model, @column, @states, @name, @transitions = model, column, states, name, {}

        instance_eval(&block) if block

        define_transition_methods
      end

      def define_transition_methods
        column, name, transitions = @column, @name, @transitions

        @model.send(:define_method, name) do
          if (to = transitions[self.send(column).to_sym])
            self.class.instance_variable_get(:@_enum_methods_module).instance_method("#{to}!").bind(self).call
          else
            false
          end
        end

        @model.send(:define_method, "#{name}!") do
          send(name) || raise('Invalid transition')
        end

        @model.send(:define_method, "can_#{name}?") do
          transitions.has_key? self.send(column).to_sym
        end

        @model.send(:define_method, "#{name}_transition") do
          transitions[self.send(column).to_sym]
        end
      end

      def transition(transitions)
        transitions.each_pair do |from, to|
          raise "Undefined state #{to}" unless @states.has_key? to
          Array(from).each do |f|
            raise "Undefined state #{f}" unless @states.has_key? f
            @transitions[f] = to
          end
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
stateful_enum-0.1.0 lib/stateful_enum/machine.rb