class FiniteMachine::DSL

A class responsible for adding state machine specific dsl

Public Class Methods

new(machine, attrs) click to toggle source

Initialize top level DSL

@api public

Calls superclass method FiniteMachine::GenericDSL::new
# File lib/finite_machine/dsl.rb, line 63
def initialize(machine, attrs)
  super(machine, attrs)

  @machine.state = FiniteMachine::DEFAULT_STATE
  @defer_initial = true
  @silent_initial = true

  initial(@attrs[:initial])   if @attrs[:initial]
  terminal(@attrs[:terminal]) if @attrs[:terminal]
  log_transitions(@attrs.fetch(:log_transitions, false))
end

Public Instance Methods

alias_target(*aliases) click to toggle source

Add aliases for the target object

@example

FiniteMachine.define do
  target_alias :engine

  on_transition do |event|
    engine.state = event.to
  end
end

@param [Array<Symbol>] aliases

the names for target alias

@api public

# File lib/finite_machine/dsl.rb, line 90
def alias_target(*aliases)
  aliases.each do |alias_name|
    next if env.aliases.include?(alias_name)

    env.aliases << alias_name
  end
end
event(name, transitions = {}, &block) click to toggle source

Create event and associate transition

@example

event :go, :green => :yellow
event :go, :green => :yellow, if: :lights_on?

@param [Symbol] name

the event name

@param [Hash] transitions

the event transitions and conditions

@return [Transition]

@api public

# File lib/finite_machine/dsl.rb, line 172
def event(name, transitions = {}, &block)
  detect_event_conflict!(name) if machine.auto_methods?

  if block_given?
    merger = ChoiceMerger.new(machine, name, transitions)
    merger.instance_eval(&block)
  else
    transition_builder = TransitionBuilder.new(machine, name, transitions)
    transition_builder.call(transitions)
  end
end
handle(*exceptions, &block) click to toggle source

Add error handler

@param [Array] exceptions

@example

handle InvalidStateError, with: :log_errors

@return [Array]

@api public

# File lib/finite_machine/dsl.rb, line 194
def handle(*exceptions, &block)
  @machine.handle(*exceptions, &block)
end
initial(value, options = {}) click to toggle source

Define initial state

@param [Symbol] value

The initial state name.

@param [Hash] options @option options [Symbol] :event

The event name.

@option options [Symbol] :defer

Set to true to defer initial state transition.
Default false.

@option options [Symbol] :silent

Set to true to disable callbacks.
Default true.

@example

initial :green

@example Defer initial event

initial state: green, defer: true

@example Trigger callbacks

initial :green, silent: false

@example Redefine event name

initial :green, event: :start

@param [String, Hash] value

@return [StateMachine]

@api public

# File lib/finite_machine/dsl.rb, line 129
def initial(value, options = {})
  state = (value && !value.is_a?(Hash)) ? value : raise_missing_state
  name, @defer_initial, @silent_initial = *parse_initial(options)
  @initial_event = name
  event(name, FiniteMachine::DEFAULT_STATE => state, silent: @silent_initial)
end
log_transitions(value) click to toggle source

Decide whether to log transitions

@api public

# File lib/finite_machine/dsl.rb, line 201
def log_transitions(value)
  self.log_transitions = value
end
terminal(*values) click to toggle source

Define terminal state

@example

terminal :red

@return [FiniteMachine::StateMachine]

@api public

# File lib/finite_machine/dsl.rb, line 154
def terminal(*values)
  self.terminal_states = values
end
trigger_init() click to toggle source

Trigger initial event

@return [nil]

@api private

# File lib/finite_machine/dsl.rb, line 141
def trigger_init
  method = @silent_initial ? :transition : :trigger
  @machine.public_send(method, :"#{@initial_event}") unless @defer_initial
end

Private Instance Methods

parse_initial(options) click to toggle source

Parse initial options

@param [Hash] options

the options to extract for initial state setup

@return [Array]

@api private

# File lib/finite_machine/dsl.rb, line 215
def parse_initial(options)
  [options.fetch(:event) { FiniteMachine::DEFAULT_EVENT_NAME },
   options.fetch(:defer) { false },
   options.fetch(:silent) { true }]
end
raise_missing_state() click to toggle source

Raises missing state error

@raise [MissingInitialStateError]

Raised when state name is not provided for initial.

@return [nil]

@api private

# File lib/finite_machine/dsl.rb, line 229
def raise_missing_state
  raise MissingInitialStateError,
        "Provide state to transition :to for the initial event"
end