Project

statum

0.0
No commit activity in last 3 years
No release in over 3 years
Ruby state machine
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.16
~> 0.8
~> 0.11
~> 10.0
~> 3.0
 Project Readme

Statum

Build Status Coverage Status Gem Version

Finite state machine for your objects

Supported Ruby 2.2.0+

  • Installation
  • Usage
    • Basic usage
    • Multiple state machines
    • Hooks
  • Contributing
  • License

Installation

Add this line to your application's Gemfile:

gem 'statum'

And then execute:

$ bundle

Or install it yourself as:

$ gem install statum

Usage

Basic usage

Statum provides a DSL for defining state machine for your class

class Car
  include Statum
  
  attr_accessor :state
  
  statum :state, initial: :idle do
    state :idle
    state :riding
    
    event :ride, idle: :riding
  end
end

Then Car object will receive following methods:

car = Car.new
car.idle? # => true
car.riding? # => false
car.ride! # changes idle state to riding

You can define an array of states which will be able to fire event:

class Car
  include Statum
  
  attr_accessor :state
  
  statum :state, initial: :idle do
    state :idle
    state :parked
    state :riding
    
    event :ride, %i[idle parked] => :riding
  end
end

Also you can use any_state helper to say, that event can be fired from any of defined states

class Car
  include Statum
  
  attr_accessor :state
  
  statum :state, initial: :idle do
    state :idle
    state :parked
    state :riding
    
    event :ride, any_state => :riding
  end
end

Multiple state machines

You can define more than one state machine on your object.

IMPORTANT use unique fields to work with two or more states

class Car
  include Statum

  attr_accessor :state, :engine

  statum :state do
    state :riding
    state :idle

    event :ride, idle: :riding
  end

  statum :engine do
    state :stopped
    state :started

    event :start, stopped: :started
  end
end
car = Car.new
car.start! # changes engine to started
car.ride! # changes state to riding

Hooks

You can be able to execute some procs before and after event will be fired

class Car
  include Statum
  
  attr_accessor :state, :started
  
  statum :state, initial: :idle do
    state :idle
    state :riding
    
    event :ride, idle: :riding,
                 before: -> { self.started = true },
                 after: :stop_engine
  end
  
  def stop_engine
    self.started = false
  end
end

And then before state changes will be executed before proc, and after changing - after proc (in instance context).

If you will wait for argument in hook - the instance will be passed.

...
event :ride, idle: :riding, 
             before: -> (instance) { instance.started = true}
...

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/nulldef/statum.

License

The gem is available as open source under the terms of the MIT License.