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 -```