https://github.com/hopsoft/state_jacket
A simple & intuitive state machine
https://github.com/hopsoft/state_jacket
ruby state-machine state-transitions
Last synced: 9 months ago
JSON representation
A simple & intuitive state machine
- Host: GitHub
- URL: https://github.com/hopsoft/state_jacket
- Owner: hopsoft
- License: mit
- Created: 2013-01-16T18:05:55.000Z (over 13 years ago)
- Default Branch: master
- Last Pushed: 2025-06-15T00:04:07.000Z (11 months ago)
- Last Synced: 2025-06-25T16:02:08.767Z (10 months ago)
- Topics: ruby, state-machine, state-transitions
- Language: Ruby
- Homepage:
- Size: 276 KB
- Stars: 10
- Watchers: 2
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
[](https://codeclimate.com/github/hopsoft/state_jacket/maintainability)
[](https://travis-ci.org/hopsoft/state_jacket)
[](https://coveralls.io/r/hopsoft/state_jacket?branch=master)
[](http://rubygems.org/gems/state_jacket)
# StateJacket
## An Intuitive [State Transition System](http://en.wikipedia.org/wiki/State_transition_system) & [State Machine](https://en.wikipedia.org/wiki/Finite-state_machine)
StateJacket provides an intuitive approach to building complex state machines
by isolating the concerns of the state transition system & state machine.
## Install
```sh
gem install state_jacket
```
## Example
Let's define states & transitions (i.e. the state transition system) & a state machine for a [turnstyle](http://en.wikipedia.org/wiki/Finite-state_machine#Example:_a_turnstile).

### State Transition System
```ruby
system = StateJacket::StateTransitionSystem.new
system.add :opened => [:closed, :errored]
system.add :closed => [:opened, :errored]
system.lock # prevent further changes
system.to_h.inspect # => {"opened"=>["closed", "errored"], "closed"=>["opened", "errored"], "errored"=>nil}
system.transitioners # => ["opened", "closed"]
system.terminators # => ["errored"]
system.can_transition? :opened => :closed # => true
system.can_transition? :closed => :opened # => true
system.can_transition? :errored => :opened # => false
system.can_transition? :errored => :closed # => false
```
### State Machine
Define the events that trigger transitions defined by the state transition system (i.e. the state machine).
```ruby
machine = StateJacket::StateMachine.new(system, state: "closed")
machine.on :open, :closed => :opened
machine.on :close, :opened => :closed
machine.lock # prevent further changes
machine.to_h.inspect # => {"open"=>[{"closed"=>"opened"}], "close"=>[{"opened"=>"closed"}]}
machine.events # => ["open", "close"]
machine.state # => "closed"
machine.is_event? :open # => true
machine.is_event? :close # => true
machine.is_event? :other # => false
machine.can_trigger? :open # => true
machine.can_trigger? :close # => false
machine.state # => "closed"
machine.trigger :open # => "opened"
machine.state # => "opened"
# you can also pass a block when triggering events
machine.trigger :close do |from_state, to_state|
# custom logic can be placed here
from_state # => "opened"
to_state # => "closed"
end
machine.state # => "closed"
# this is a noop because can_trigger?(:close) is false
machine.trigger :close # => nil
machine.state # => "closed"
begin
machine.trigger :open do |from_state, to_state|
raise # the transition isn't performed if an error occurs in the block
end
rescue
end
machine.state # => "closed"
```