README.rdoc in state_machine-0.4.1 vs README.rdoc in state_machine-0.4.2

- old
+ new

@@ -34,30 +34,36 @@ state machine is :) Some brief, high-level features include: * Defining state machines on any Ruby class * Multiple state machines on a single class +* Namespaced state machines * before/after transition hooks with explicit transition requirements * ActiveRecord integration * DataMapper integration * Sequel integration * States of any data type * State predicates +* State-driven behavior * GraphViz visualization creator Examples of the usage patterns for some of the above features are shown below. You can find more detailed documentation in the actual API. == Usage === Example -Below is an example of many of the features offered by this plugin, including +Below is an example of many of the features offered by this plugin, including: * Initial states +* Namespaced states * Transition callbacks * Conditional transitions +* State-driven behavior +Class definition: + class Vehicle attr_accessor :seatbelt_on state_machine :state, :initial => 'parked' do before_transition :from => %w(parked idling), :do => :put_on_seatbelt @@ -96,14 +102,43 @@ end event :repair do transition :to => 'parked', :from => 'stalled', :if => :auto_shop_busy? end + + state 'parked' do + def speed + 0 + end + end + + state 'idling', 'first_gear' do + def speed + 10 + end + end + + state 'second_gear' do + def speed + 20 + end + end end + state_machine :hood_state, :initial => 'closed', :namespace => 'hood' do + event :open do + transition :to => 'opened', :from => 'closed' + end + + event :close do + transition :to => 'closed', :from => 'opened' + end + end + def initialize @seatbelt_on = false + super() # NOTE: This *must* be called, otherwise states won't get initialized end def put_on_seatbelt @seatbelt_on = true end @@ -126,24 +161,43 @@ vehicle = Vehicle.new # => #<Vehicle:0xb7cf4eac @state="parked", @seatbelt_on=false> vehicle.parked? # => true vehicle.can_ignite? # => true vehicle.next_ignite_transition # => #<StateMachine::Transition:0xb7c34cec ...> + vehicle.speed # => 0 + vehicle.ignite # => true vehicle.parked? # => false vehicle.idling? # => true + vehicle.speed # => 10 vehicle # => #<Vehicle:0xb7cf4eac @state="idling", @seatbelt_on=true> + vehicle.shift_up # => true + vehicle.speed # => 10 vehicle # => #<Vehicle:0xb7cf4eac @state="first_gear", @seatbelt_on=true> + vehicle.shift_up # => true + vehicle.speed # => 20 vehicle # => #<Vehicle:0xb7cf4eac @state="second_gear", @seatbelt_on=true> # The bang (!) operator can raise exceptions if the event fails vehicle.park! # => StateMachine::InvalidTransition: Cannot transition via :park from "second_gear" # Generic state predicates can raise exceptions if the value does not exist vehicle.state?('parked') # => true vehicle.state?('invalid') # => ArgumentError: "parked" is not a known state value + + # Namespaced machines have uniquely-generated methods + vehicle.can_open_hood? # => true + vehicle.open_hood # => true + vehicle.can_close_hood? # => true + + vehicle.hood_opened? # => true + vehicle.hood_closed? # => false + +*Note* the comment made on the +initialize+ method in the class. In order for +state machine attributes to be properly initialized, <tt>super()</tt> must be called. +See StateMachine::MacroMethods for more information about this. == Integrations In addition to being able to define state machines on all Ruby classes, a set of out-of-the-box integrations are available for some of the more popular Ruby