Home > SimpleMachine

SimpleMachine

SimpleMachine is a project mainly written in Ruby, it's free.

SimpleMachine is module for Ruby which injects simple state machine behavior in any class that includes it

= SimpleMachine

SimpleMachine is module for Ruby which injects simple state machine behavior in any class that includes it. It can be defined on multiple fields in the same class

== Installation

Install it with "gem install simple_machine" then require 'simple_machine' in your project, or if you use Bundler add this to your Gemfile: gem "simple_machine"

== Usage

After requiring 'simple_machine' inject state machine in your class like this:

require 'simple_machine'

class Phone include SimpleMachine
implement_state_machine_for :my_state do initial_state :off other_states :ready, :dialing, :busy allow_transition :turn_on, :from => :off, :to => :ready allow_transition :dial, :from => :ready, :to => :dialing allow_transition :hangup, :from => :dialing, :to => :ready allow_transition :hangup, :from => :busy, :to => :ready allow_transition :turn_off, :from => :ready, :to => :off do

self is set to phone instance

    puts my_state #=> :ready  
    # do something before transition ...
    true # state will be changed to :off if block returns true  
  end
  after_transition do
    # self is set to phone instance
    puts "New state is '#{my_state}'"
  end
end 

end

This chunk of code produces following effects:

Phone.my_state_default_state #=> :off phone = Phone.new phone.my_state #=> :off phone.my_state_machine.allowed_transitions #=> [:turn_on] phone.my_state_machine.can_dial? #=> false phone.my_state_machine.dial #=> raises exception: 'Invalid transition #dial from 'off' state' phone.my_state_machine.can_turn_on? #=> true phone.my_state_machine.turn_on #=> :ready phone.my_state #=> :ready

=== Transition Guards

You can also implement transition guards in your class like this:

class Phone def guard_for_dial_on_my_state; false; end end

In this case even if +dial+ is allowed transition from +ready+ state this is what will happen:

phone.my_state #=> :ready phone.my_state_machine.allowed_transitions #=> [:hangup] phone.my_state.machine.can_dial? #=> false phone.my_state_machine.dial #=> raises exception: 'Unable to dial due to guard'

=== Callback

After each transition callback is invoked if it is defined:

class Phone include SimpleMachine
implement_state_machine_for :my_state do

...

  after_transition do
    # self is set to phone instance
    puts "New state is '#{my_state}'"
  end
end

end

== Test

If you want to run tests you will need 'rspec' and 'mocha' gems

== Disclaimer

This library was made without any pretend to be big-enterprise-sega-mega solution for State machine, but I still hope you will find this small library useful in some cases (I already do :). If you have any issues or ideas feel free to fork the project and send a pull request.

Previous:byngle