README.md in simple_states-2.0.0 vs README.md in simple_states-2.0.1
- old
+ new
@@ -1,140 +1,80 @@
# simple\_states [![Build Status](https://secure.travis-ci.org/svenfuchs/simple_states.png)](http://travis-ci.org/svenfuchs/simple_states)
A super-slim (~200 loc) statemachine-like support library focussed on use in
Travis CI.
+Note that the current version behaves slightly differently, and comes with
+reduced features compared to the original version. If you are looking for the
+original version see the tag `v1.1.0.rc11`.
+
## Usage
Define states and events like this:
``` ruby
class Foo
include SimpleStates
- states :created, :started, :finished
+ event :start, if: :start?
+ event :finish, to: [:passed, :failed], after: :notify, unless: :finished?
- event :start, :from => :created, :to => :started, :if => :startable?
- event :finish, :to => :finished, :after => :cleanup
-
attr_accessor :state, :started_at, :finished_at
def start
# start foo
end
- def startable?
+ def start?
true
end
- def cleanup
- # cleanup foo
+ def notify(event)
+ # notify about event on foo
end
end
```
-Including the SimpleStates module to your class is currently required. We'll add
-hooks for ActiveRecord etc later.
-
SimpleStates expects your model to support attribute accessors for `:state`.
Event options have the following well-known meanings:
``` ruby
-:from # valid states to transition from
-:to # target state to transition to
+:to # allowed target states to transition to, deferred from the event name if not given
:if # only proceed if the given method returns true
:unless # only proceed if the given method returns false
:before # run the given method before running `super` and setting the new state
:after # run the given method at the very end
```
-All of these options except for `:to` can be given as a single symbol or string or
-as an Array of symbols or strings.
+All of these options except can be given as a single symbol or string or as an
+Array of symbols or strings.
Calling `event` will effectively add methods to a proxy module which is
-included to the singleton class of your class' instances. E.g. declaring `event
-:start` in the example above will add methods `start` and `start!` to a module
-included to the singleton class of instances of `Foo`.
+prepended to your class (included to the singleton class of your class'
+instances on 1.9). E.g. declaring `event :start` in the example above will add
+methods `start` and `start!` to a module included to the singleton class of
+instances of `Foo`.
This method will
1. check if `:if`/`:unless` conditions apply (if given) and just return from the method otherwise
-2. check if the object currently is in a valid `:from` state (if given) and raise an exception otherwise
-3. run `:before` callbacks (if given)
-4. call `super` if Foo defines the current method (i.e. call `start` but not `finish` in the example above)
-5. add the object's current state to its `past_states` history
-6. set the object's `state` to the target state given as `:to`
-7. set the object's `[state]_at` attribute to `Time.now` if the object defines a writer for it
-8. run `:after` callbacks (if given)
+2. run `:before` callbacks (if given)
+3. set the object's `state` to the target state
+4. set the object's `[state]_at` attribute to `Time.now` if the object defines a writer for it
+5. call `super` if Foo defines the current method (i.e. call `start` but not `finish` in the example above)
+6. run `:after` callbacks (if given)
You can define options for all events like so:
``` ruby
-event :finish, :to => :finished, :after => :cleanup
-event :all, :after => :notify
+event :finish, after: :cleanup
+event :all, after: :notify
```
This will call :cleanup first and then :notify on :finish.
If no target state was given for an event then SimpleStates will try to derive
-it from the states list. I.e. for an event `start` it will check the states
+it from the event name. I.e. for an event `start` it will check the states
list for a state `started` and use it. If it can not find a target state this
way then it will raise an exception.
-By default SimpleStates will assume `:created` as an initial state. You can
-overwrite this using:
-
-``` ruby
-# note that we have to use self here!
-self.initial_state = :some_state
-```
-
-So with the example above something the following would work:
-
-``` ruby
-foo = Foo.new
-
-foo.state # :created
-foo.created? # true
-foo.was_created? # true
-foo.state?(:created) # true
-
-foo.start # checks Foo#startable? and then calls Foo#start
-# calling foo.start! (with exclamation mark) would perform same actions as foo.start, but
-# also call foo.save! afterwards.
-
-foo.state # :started
-foo.started? # true
-foo.started_at # Time.now
-foo.created? # false
-foo.was_created? # true
-
-foo.finish # just performs state logic as there's no Foo#finish
-
-foo.state # :finished
-foo.finished? # true
-foo.finished_at # Time.now
-foo.was_created? # true
-foo.was_started? # true
-```
-
-In order to treat states as "ordered", the option `ordered: true` can be
-passed. Events will still behave the same, callbacks be called, etc. However,
-the `state` attribute will never be set back to a previous state.
-
-For example:
-
-```
-class Foo
- include SimpleStates
-
- states :created, :started, :finished, ordered: true
-end
-
-foo = Foo.new
-foo.finish
-foo.start
-
-p foo.state
-# => :finished
-```