soveran-micromachine 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +48 -3
- data/Rakefile +0 -27
- data/lib/micromachine.rb +0 -20
- data/micromachine.gemspec +14 -0
- metadata +2 -1
data/README.markdown
CHANGED
@@ -11,7 +11,7 @@ all provide a nice DSL for declaring events, exceptions, callbacks,
|
|
11
11
|
and all kinds of niceties in general.
|
12
12
|
|
13
13
|
But if all you want is a finite state machine, look no further: this is only
|
14
|
-
|
14
|
+
22 lines of code and provides everything a finite state machine must have, and
|
15
15
|
nothing more.
|
16
16
|
|
17
17
|
Usage
|
@@ -36,11 +36,56 @@ It can also have callbacks when entering some state:
|
|
36
36
|
puts "Confirmed"
|
37
37
|
end
|
38
38
|
|
39
|
+
Adding MicroMachine to your models
|
40
|
+
----------------------------------
|
41
|
+
|
42
|
+
The most popular pattern among Ruby libraries that tackle this problem
|
43
|
+
is to extend the model and transform it into a finite state machine.
|
44
|
+
Instead of working as a mixin, MicroMachine's implementation is by
|
45
|
+
composition: you instantiate a finite state machine (or many!) inside
|
46
|
+
your model and you are in charge of querying and persisting the state.
|
47
|
+
Here's an example of how to use it with an ActiveRecord model:
|
48
|
+
|
49
|
+
class Event < ActiveRecord::Base
|
50
|
+
before_save :persist_confirmation
|
51
|
+
|
52
|
+
def confirm!
|
53
|
+
confirmation.trigger(:confirm)
|
54
|
+
end
|
55
|
+
|
56
|
+
def cancel!
|
57
|
+
confirmation.trigger(:cancel)
|
58
|
+
end
|
59
|
+
|
60
|
+
def reset!
|
61
|
+
confirmation.trigger(:reset)
|
62
|
+
end
|
63
|
+
|
64
|
+
def confirmation
|
65
|
+
@confirmation ||= begin
|
66
|
+
@confirmation = MicroMachine.new(confirmation_state || "pending")
|
67
|
+
@confirmation.transitions_for[:confirm] = { "pending" => "confirmed" }
|
68
|
+
@confirmation.transitions_for[:cancel] = { "confirmed" => "cancelled" }
|
69
|
+
@confirmation.transitions_for[:reset] = { "confirmed" => "pending", "cancelled" => "pending" }
|
70
|
+
@confirmation
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def persist_confirmation
|
77
|
+
self.confirmation_state = confirmation.state
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
This example asumes you have a :confirmation_state attribute in your
|
82
|
+
model. This may look like a very verbose implementation, but you gain a
|
83
|
+
lot in flexibility.
|
84
|
+
|
39
85
|
Installation
|
40
86
|
------------
|
41
87
|
|
42
|
-
$ gem
|
43
|
-
$ sudo gem install soveran-micromachine
|
88
|
+
$ sudo gem install micromachine
|
44
89
|
|
45
90
|
License
|
46
91
|
-------
|
data/Rakefile
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/gempackagetask'
|
3
1
|
require 'rake/testtask'
|
4
|
-
require 'rake/clean'
|
5
|
-
|
6
|
-
gem_spec_file = 'micromachine.gemspec'
|
7
|
-
|
8
|
-
gem_spec = eval(File.read(gem_spec_file)) rescue nil
|
9
2
|
|
10
3
|
task :default => :test
|
11
4
|
|
@@ -13,23 +6,3 @@ Rake::TestTask.new(:test) do |t|
|
|
13
6
|
t.pattern = 'test/**/*_test.rb'
|
14
7
|
t.verbose = false
|
15
8
|
end
|
16
|
-
|
17
|
-
Rake::GemPackageTask.new(gem_spec) do |pkg|
|
18
|
-
pkg.need_zip = false
|
19
|
-
pkg.need_tar = false
|
20
|
-
rm_f FileList['pkg/**/*.*']
|
21
|
-
end if gem_spec
|
22
|
-
|
23
|
-
desc "Generate the gemspec file."
|
24
|
-
task :gemspec do
|
25
|
-
require 'erb'
|
26
|
-
|
27
|
-
File.open(gem_spec_file, 'w') do |f|
|
28
|
-
f.write ERB.new(File.read("#{gem_spec_file}.erb")).result(binding)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
desc "Builds and installs the gem."
|
33
|
-
task :install => :repackage do
|
34
|
-
`sudo gem install pkg/#{gem_spec.name}-#{gem_spec.version}.gem`
|
35
|
-
end
|
data/lib/micromachine.rb
CHANGED
@@ -1,23 +1,3 @@
|
|
1
|
-
# Finite State Machine
|
2
|
-
#
|
3
|
-
# Usage:
|
4
|
-
#
|
5
|
-
# machine = MicroMachine.new(:new) # Initial state.
|
6
|
-
#
|
7
|
-
# machine.transitions_for[:confirm] = { :new => :confirmed }
|
8
|
-
# machine.transitions_for[:ignore] = { :new => :ignored }
|
9
|
-
# machine.transitions_for[:reset] = { :confirmed => :new, :ignored => :new }
|
10
|
-
#
|
11
|
-
# machine.trigger(:confirm) #=> true
|
12
|
-
# machine.trigger(:ignore) #=> false
|
13
|
-
# machine.trigger(:reset) #=> true
|
14
|
-
# machine.trigger(:ignore) #=> true
|
15
|
-
#
|
16
|
-
# It also handles callbacks that are executed when entering a different state.
|
17
|
-
#
|
18
|
-
# machine.on(:confirmed) do
|
19
|
-
# puts "Confirmed"
|
20
|
-
# end
|
21
1
|
class MicroMachine
|
22
2
|
attr :transitions_for
|
23
3
|
attr :state
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'micromachine'
|
3
|
+
s.version = '0.0.7'
|
4
|
+
s.summary = %{Minimal Finite State Machine.}
|
5
|
+
s.date = %q{2009-03-07}
|
6
|
+
s.author = "Michel Martens"
|
7
|
+
s.email = "michel@soveran.com"
|
8
|
+
s.homepage = "http://github.com/soveran/micromachine"
|
9
|
+
s.files = ["lib/micromachine.rb", "README.markdown", "LICENSE", "Rakefile", "micromachine.gemspec", "example/micromachine_sample.rb", "example/micromachine_sample_gem.rb"]
|
10
|
+
s.require_paths = ['lib']
|
11
|
+
s.has_rdoc = false
|
12
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
13
|
+
end
|
14
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soveran-micromachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
@@ -26,6 +26,7 @@ files:
|
|
26
26
|
- README.markdown
|
27
27
|
- LICENSE
|
28
28
|
- Rakefile
|
29
|
+
- micromachine.gemspec
|
29
30
|
- example/micromachine_sample.rb
|
30
31
|
- example/micromachine_sample_gem.rb
|
31
32
|
has_rdoc: false
|