Class: SimpleState::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_state/builder.rb

Overview

Responsible for taking a state machine block and building the methods.

The builder is run whenever you call state_machine on a class and does a number of things.

* Firstly, it adds a :state reader if one is not defined, and a
  _private_ :state writer.

* It adds a +states+ method to the class, used for easily accessing
  the list of states for the class, and the events belonging to each
  state (and the state that the event transitions to).

* Four internal methods +initial_state+, +initial_state=+,
  +_determine_new_state+ and +_valid_transition+ which are used
  internally by SimpleState for aiding the transition from one state to
  another.

Defined Under Namespace

Classes: StateBuilder

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Builder

Returns a new instance of Builder.



21
22
23
# File 'lib/simple_state/builder.rb', line 21

def initialize(klass)
  @klass = klass
end

Instance Method Details

#build(&blk) ⇒ Object

Trigger for building the state machine methods.



28
29
30
31
32
33
34
35
36
37
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
66
67
68
# File 'lib/simple_state/builder.rb', line 28

def build(&blk)
  @klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    include ::SimpleState::Mixins
  RUBY

  # Create an anonymous module which will be added to the state machine
  # class's inheritance chain.
  mod = @mod = Module.new
  mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def self.inspect
      "SimpleState::#{@klass}AnonMixin"
    end

    # Handles the change of state.
    # @api private
    def _change_state_using_event!(event)
      self.state = self.class._determine_new_state(self.state, event)
    end

    # Returns if the passed event is permitted with the instance in it's
    # current state.
    # @api public
    def event_permitted?(event)
      self.class._event_permitted?(self.state, event)
    end

    # Returns true if the given symbol matches the current state.
    # @api public
    def in_state?(state)
      self.state == state
    end
  RUBY

  # Declare the state machine rules.
  instance_eval(&blk)

  # Insert the anonymous module.
  @klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    include mod
  RUBY
end

#state(name, &blk) ⇒ Object

Defines a new state.

Parameters:

  • name (Symbol)

    The name of the state.

  • &blk (Block)

    An optional block for defining transitions for the state. If no block is given, the state will be an end-point.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/simple_state/builder.rb', line 79

def state(name, &blk)
  @klass.states[name] = []
  @klass.initial_state ||= name

  @mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def #{name}?           # def prepared?
      in_state?(:#{name})  #   self.state == :prepared
    end                    # end
  RUBY

  # Define transitions for this state.
  StateBuilder.new(@klass, @mod, name).build(&blk) if blk
end