11# Evolve
22
3- ## Handling unknown events
3+ ## Match by event
44
55``` ruby
6+ Event = Data .define(:value )
7+
68decider = Decider .define do
79 initial_state :initial
10+
11+ evolve Event do
12+ event.value
13+ end
814end
15+
16+ decider.evolve decider.initial_state, Event .new (value: :changed )
17+ # > :changed
918```
1019
11- Return state (nothing changed) by default:
20+ ## Match by state and event
1221
1322``` ruby
23+ decider = Decider .define do
24+ initial_state :turned_off
25+
26+ evolve :turned_on , :turned_off do
27+ event
28+ end
29+
30+ evolve :turned_off , :turned_on do
31+ event
32+ end
33+ end
34+
35+ decider.evolve decider.initial_state, :turned_on
36+ # > :turned_on
37+ decider.evolve :turned_on , :turned_off
38+ # > :turned_off
39+ decider.evolve :turned_on , :unknown
40+ # > :turned_on
41+ ```
42+
43+ ## Match by pattern matching
44+
45+ ``` ruby
46+ State = Data .define(:value )
47+ Event = Data .define(:value )
48+
49+ decider = Decider .define do
50+ initial_state State .new (value: :turned_off )
51+
52+ evolve proc { [state, event] in [State (value: :turned_off ), Event (value: :turned_on )] } do
53+ state.with(value: event.value)
54+ end
55+ end
56+
57+ decider.evolve decider.initial_state, Event .new (value: :turned_on )
58+ # > #<data State value=:turned_on>
1459decider.evolve decider.initial_state, :unknown
60+ # > #<data State value=:turned_off>
61+ ```
62+
63+ ## Handling unknown events
64+
65+ ``` ruby
66+ decider = Decider .define do
67+ initial_state :initial
68+ end
69+
70+ decider.decide decider.initial_state, :initial
1571# > :initial
1672```
1773
18- Raise error when using ` evolve! ` :
74+ If you want to raise error, define a catch-all as last one :
1975
2076``` ruby
21- decider.evolve! decider.initial_state, :unknown
22- # > raise ArgumentError, Unknown event
77+ decider = Decider .define do
78+ initial_state :initial
79+
80+ evolve proc { true } do
81+ raise ArgumentError , " Unknown event #{ event } "
82+ end
83+ end
84+ decider.evolve decider.initial_state, :unknown
85+ # > Unknown event unknown (ArgumentError)
2386```
2487
2588## Events
@@ -30,11 +93,11 @@ Events can be primitives like symbols:
3093decider = Decider .define do
3194 initial_state :initial
3295
33- evolve :started do | state , event |
96+ evolve :started do
3497 :started
3598 end
3699
37- evolve :stopped do | state , event |
100+ evolve :stopped do
38101 :stopped
39102 end
40103end
@@ -50,13 +113,38 @@ Stopped = Data.define
50113decider = Decider .define do
51114 initial_state State .new (speed: 0 )
52115
53- evolve Started do | state , event |
54- State . new (speed: event.speed)
116+ evolve State , Started do
117+ state.with (speed: event.speed)
55118 end
56119
57- evolve Stopped do | state , event |
120+ evolve State , Stopped do
58121 State .new (speed: 0 )
59122 end
60123end
61124```
62125
126+ ## Calculate state
127+
128+ In most cases you want to take a collection of events and reduce them with ` evolve ` to calculate the state, like:
129+
130+ ``` ruby
131+ decider = Decider .define do
132+ initial_state 0
133+
134+ evolve :increased do
135+ state + 1
136+ end
137+ end
138+
139+ [:increased , :increased ].reduce(decider.initial_state) { |state , event | decider.evolve(state, event) }
140+ # > 2
141+ ```
142+
143+ You can shortcut that with ` & ` :
144+
145+ ``` ruby
146+ [:increased , :increased ].reduce(decider.initial_state, & decider.method(:evolve ))
147+ # > 2
148+ [:increased , :increased ].reduce(decider.initial_state, & decider.evolve)
149+ # > 2
150+ ```
0 commit comments