Created
April 13, 2010 08:58
-
-
Save godfat/364446 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'aasm' | |
class Cat | |
include AASM | |
attr_writer :stomach | |
# how would you like to read the state? | |
# database? memcache? | |
def aasm_read_state | |
puts " read: Examining stomach... #{@stomach || 'nothing'}!" | |
@stomach || self.class.aasm_initial_state | |
end | |
# how would you like to write the state? | |
# database? memcache? only save it when state changed | |
def aasm_write_state_without_persistence food | |
puts "write: Eating... #{food}!" | |
@stomach = food if food != @stomach | |
end | |
aasm_initial_state :nothing | |
# state exit callback and state enter callback | |
aasm_state :nothing, :exit => :ate | |
aasm_state :fish, :enter => :found | |
# guard if this transition could process | |
aasm_event :eat do | |
transitions :from => [:nothing], | |
:to => :fish, | |
:guard => :fish_left? | |
end | |
# state transition callback | |
aasm_event :digest do | |
transitions :from => [:fish, :nothing], | |
:to => :nothing, | |
:on_transition => :digesting | |
end | |
def ate | |
puts " exit: Ate #{aasm_current_state}..." | |
end | |
# don't do this, state callback would be called | |
# when reading from database/memcache to initialize | |
# so this would yield unexpected result. | |
# state callback should have no side-effect at all. | |
# put side-effect only in transition callback | |
def found | |
puts "enter: Found #{@fish_amount} fish left!" | |
@fish_amount -= 1 | |
end | |
def fish_left? | |
puts "guard: fish left: #{@fish_amount ||= 2}" | |
@fish_amount > 0 | |
end | |
def digesting | |
puts "on_transition: Digesting #{aasm_current_state}..." | |
end | |
def silence_exception e | |
puts "ate exception #{e.inspect}" | |
end | |
aasm_events.each{ |(name, event)| | |
event.update(event.options.merge(:error => :silence_exception)) | |
} | |
# pool man's state pattern | |
def say | |
send("say_#{aasm_current_state}") | |
end | |
def say_nothing | |
puts ' say: I have nothing...' | |
end | |
def say_fish | |
puts ' say: I have fish!' | |
end | |
end | |
def test c = Cat.new | |
puts '-'*30 | |
puts 'c.digest'; c.digest; puts | |
puts 'c.eat' ; c.eat ; puts | |
puts 'c.digest'; c.digest; puts | |
puts 'c.digest'; c.digest; puts | |
puts 'c.eat' ; c.eat ; puts | |
puts 'c.say' ; c.say ; puts | |
c.send(:instance_variable_set, '@aasm_current_state', nil) | |
c | |
end | |
c = test(test) | |
c.send(:aasm_current_state=, :fish) | |
c.eat | |
__END__ | |
~> ruby -v | |
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-darwin10] | |
~> gem list aasm | |
*** LOCAL GEMS *** | |
aasm (2.1.5) | |
~> ruby cat.rb | |
------------------------------ | |
c.digest | |
read: Examining stomach... nothing! | |
exit: Ate nothing... | |
on_transition: Digesting nothing... | |
write: Eating... nothing! | |
c.eat | |
exit: Ate nothing... | |
guard: fish left: 2 | |
enter: Found 2 fish left! | |
write: Eating... fish! | |
c.digest | |
on_transition: Digesting fish... | |
write: Eating... nothing! | |
c.digest | |
exit: Ate nothing... | |
on_transition: Digesting nothing... | |
write: Eating... nothing! | |
c.eat | |
exit: Ate nothing... | |
guard: fish left: 1 | |
enter: Found 1 fish left! | |
write: Eating... fish! | |
c.say | |
say: I have fish! | |
------------------------------ | |
c.digest | |
read: Examining stomach... fish! | |
on_transition: Digesting fish... | |
write: Eating... nothing! | |
c.eat | |
exit: Ate nothing... | |
guard: fish left: 0 | |
c.digest | |
exit: Ate nothing... | |
on_transition: Digesting nothing... | |
write: Eating... nothing! | |
c.digest | |
exit: Ate nothing... | |
on_transition: Digesting nothing... | |
write: Eating... nothing! | |
c.eat | |
exit: Ate nothing... | |
guard: fish left: 0 | |
c.say | |
say: I have nothing... | |
write: Eating... fish! | |
ate exception #<AASM::InvalidTransition: Event 'eat' cannot transition from 'fish'> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment