StateMethods
Suppose you wish to define method which executes code dependent on a state of an instance:
def state_method(*args)
case state
when :a then ...
when :b then ...
...
end
Now suppose you would like this generic behaviour (say coming from an included module or subclass) but would like to override it in some states. You need to rewrite the whole function and fall back to super.
This implementation of state dependence makes it unavoidable that an instance invocation matches the state against all cases especially if there is many of them and falling back to super makes it worse. Apart from this, while explicit, the case statements may be too verbose.
The state machine gem offers such state-driven instance behaviour:
class Vehicle
# ...
state_machine :state, :initial => :parked do
#... describe transitions
state :parked do
def speed
0
end
end
state :idling, :first_gear do
def speed
10
end
end
state all - [:parked, :stalled, :idling] do
def moving?
true
end
end
state :parked, :stalled, :idling do
def moving?
false
end
end
end
end
- Call state-driven behavior that's undefined for the state raises a NoMethodError
- does not allow for open ended state values
order-dependent unsafe specification, but 'all' does not override any specific state, behaves as default
allow partitions and declarative order-independent specification
open ended values
extension via inheritance
class Model
source("sm.rb")
vehicle = Vehicle.new # => #
vehicle.ignite # => true vehicle.state # => "idling" vehicle.speed # => 0 vehicle.moving? # => false
vehicle.shift_up # => true vehicle.state # => "first_gear" vehicle.speed # => 10 vehicle.moving? # => true
Installation
Add this line to your application's Gemfile:
gem 'state_methods'
And then execute:
$ bundle
Or install it yourself as:
$ gem install state_methods
Usage
TODO: Write usage instructions here
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request