You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
There are many finite state machine implementations for Ruby, and theyall provide a nice DSL for declaring events, exceptions, callbacks,and all kinds of niceties in general.
But if all you want is a finite state machine, look no further: thishas less than 50 lines of code and provides everything a finite statemachine must have, and nothing more.
Usage
require'micromachine'machine=MicroMachine.new(:new)# Initial state.# Define the possible transitions for each event.machine.when(:confirm,:new=>:confirmed)machine.when(:ignore,:new=>:ignored)machine.when(:reset,:confirmed=>:new,:ignored=>:new)machine.trigger(:confirm)#=> truemachine.state#=> :confirmedmachine.trigger(:ignore)#=> falsemachine.state#=> :confirmedmachine.trigger(:reset)#=> truemachine.state#=> :newmachine.trigger(:ignore)#=> truemachine.state#=> :ignored
Thewhen helper is syntactic sugar for assigning to thetransitions_for hash. This code is equivalent:
You can also ask if an event will trigger a change in state. Followingthe example above:
machine.state#=> :ignoredmachine.trigger?(:ignore)#=> falsemachine.trigger?(:reset)#=> true# And the state is preserved, because you were only asking.machine.state#=> :ignored
If you want to force an Exception when trying to trigger a event from anon compatible state use thetrigger! method:
# All possible eventsmachine.events#=> [:confirm, :ignore, :reset]# All events triggerable from the current statemachine.triggerable_events#=> [:confirm, :ignore]# All possible statesmachine.states#=> [:new, :confirmed, :ignored]
Check the examples directory for more information.
Adding MicroMachine to your models
The most popular pattern among Ruby libraries that tackle this problemis to extend the model and transform it into a finite state machine.Instead of working as a mixin, MicroMachine's implementation is bycomposition: you instantiate a finite state machine (or many!) insideyour model and you are in charge of querying and persisting the state.Here's an example of how to use it with an ActiveRecord model:
This example asumes you have a:confirmation_state attribute in yourmodel. This may look like a very verbose implementation, but you gain alot in flexibility.
Now, on any transition theconfirmation_state attribute in the modelwill be updated.
Installation
$ sudo gem install micromachine
License
Copyright (c) 2009 Michel Martens
Permission is hereby granted, free of charge, to any personobtaining a copy of this software and associated documentationfiles (the "Software"), to deal in the Software withoutrestriction, including without limitation the rights to use,copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom theSoftware is furnished to do so, subject to the followingconditions:
The above copyright notice and this permission notice shall beincluded in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIESOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISINGFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.