anthonyw-simple_state 0.1.1
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/LICENSE +19 -0
- data/README.markdown +143 -0
- metadata +56 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009 Anthony Williams
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# SimpleState
|
2
|
+
|
3
|
+
Yet another state machine library for Ruby.
|
4
|
+
|
5
|
+
## Why _another_ state machine library?
|
6
|
+
|
7
|
+
There are several existing implementations of state machines in Ruby, notably
|
8
|
+
[pluginaweek/state_machine][pluginaweek], [rubyist/aasm][rubyist] and
|
9
|
+
[ryan-allen/workflow][ryanallen]. However, all felt rather heavy and
|
10
|
+
cumbersome, when all I really needed was a lightweight means for setting the
|
11
|
+
state of a class instance, and transitioning from one state to another.
|
12
|
+
|
13
|
+
There is no support for adding your own code to customise transitions, nor is
|
14
|
+
is there any support for callbacks or event guards. It's called
|
15
|
+
**Simple**State for a reason! The library adds some helper methods to your
|
16
|
+
class, keeps track of the valid states, makes sure that a transition is
|
17
|
+
permitted, and that's about it.
|
18
|
+
|
19
|
+
## Why use SimpleState?
|
20
|
+
|
21
|
+
* Lightweight.
|
22
|
+
* method_missing isn't used. ;)
|
23
|
+
* No dependencies.
|
24
|
+
* No extensions to core classes.
|
25
|
+
* Tested on Ruby 1.8.6 (p287), 1.8.7 (p72), and 1.9.1 (p0).
|
26
|
+
* Uses an API similar to Workflow, which I find to be more logical than that
|
27
|
+
in the acts\_as\_state\_machine family.
|
28
|
+
|
29
|
+
## Why use something else?
|
30
|
+
|
31
|
+
* SimpleState has no support for customising transitions with your own code.
|
32
|
+
* No support for callbacks.
|
33
|
+
* No support for guard conditions.
|
34
|
+
* SimpleState forces you to use an attribute called `state` - other libraries
|
35
|
+
let you choose whatever name you want.
|
36
|
+
* Uses a class variable to keep track of transitions - doesn't lend itself
|
37
|
+
all that well to subclassing your state machines.
|
38
|
+
|
39
|
+
The three libraries mentioned above have support for callbacks and guard
|
40
|
+
conditions: if you need these features then you'd be better off choosing one
|
41
|
+
of those libraries instead of SimpleState.
|
42
|
+
|
43
|
+
## Examples
|
44
|
+
|
45
|
+
require 'rubygems'
|
46
|
+
require 'simple_state'
|
47
|
+
|
48
|
+
class SimpleStateMachine
|
49
|
+
extend SimpleState # Adds state_machine method to this class.
|
50
|
+
|
51
|
+
state_machine do
|
52
|
+
state :not_started do
|
53
|
+
event :start, :transitions_to => :started
|
54
|
+
end
|
55
|
+
|
56
|
+
state :started do
|
57
|
+
event :finish, :transitions_to => :finished
|
58
|
+
event :cancel, :transitions_to => :cancelled
|
59
|
+
end
|
60
|
+
|
61
|
+
state :finished
|
62
|
+
state :cancelled
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
SimpleState makes one assumption: that the first call to `state` in the
|
67
|
+
`state_machine` block is the default state; every instance of
|
68
|
+
SimpleStateMachine will begin with the state `:not_started`.
|
69
|
+
|
70
|
+
_Note: if you define `#initialize` in your class, you should ensure that you
|
71
|
+
call `super` or the default state won't get set._
|
72
|
+
|
73
|
+
The above example declares four states: `not_started`, `started`, `finished`
|
74
|
+
and `cancelled`. If your instance is in the `not_started` state it may
|
75
|
+
transition to the `started` state by calling `SimpleStateMachine#start!`. Once
|
76
|
+
`started` it can then transition to `finished` or `cancelled` using
|
77
|
+
`SimpleStateMachine#finish!` and `SimpleStateMachine#cancel!`.
|
78
|
+
|
79
|
+
Along with the bang methods for changing an instance's state, there are
|
80
|
+
predicate methods which will return true or false depending on the current
|
81
|
+
state of the instance.
|
82
|
+
|
83
|
+
instance = SimpleStateMachine.new # Initial state will be :not_started
|
84
|
+
|
85
|
+
instance.not_started? # => true
|
86
|
+
instance.started? # => false
|
87
|
+
instance.finished? # => false
|
88
|
+
instance.cancelled? # => false
|
89
|
+
|
90
|
+
instance.start!
|
91
|
+
|
92
|
+
instance.not_started? # => false
|
93
|
+
instance.started? # => true
|
94
|
+
instance.finished? # => false
|
95
|
+
instance.cancelled? # => false
|
96
|
+
|
97
|
+
# etc...
|
98
|
+
|
99
|
+
It is possible for the same event to be used in multiple states:
|
100
|
+
|
101
|
+
state :not_started do
|
102
|
+
event :start, :transitions_to => :started
|
103
|
+
event :cancel, :transitions_to => :cancelled # <--
|
104
|
+
end
|
105
|
+
|
106
|
+
state :started do
|
107
|
+
event :finish, :transitions_to => :finished
|
108
|
+
event :cancel, :transitions_to => :cancelled # <--
|
109
|
+
end
|
110
|
+
|
111
|
+
... or for the event to do something different depending on the object's
|
112
|
+
current state:
|
113
|
+
|
114
|
+
state :not_started do
|
115
|
+
event :start, :transitions_to => :started
|
116
|
+
event :cancel, :transitions_to => :cancelled_before_start # <--
|
117
|
+
end
|
118
|
+
|
119
|
+
state :started do
|
120
|
+
event :finish, :transitions_to => :finished
|
121
|
+
event :cancel, :transitions_to => :cancelled # <--
|
122
|
+
end
|
123
|
+
|
124
|
+
state :finished
|
125
|
+
state :cancelled
|
126
|
+
state :cancelled_before_start
|
127
|
+
|
128
|
+
## ORM Integration
|
129
|
+
|
130
|
+
SimpleState should play nicely with your ORM of choice. When an object's state
|
131
|
+
is set, `YourObject#state=` is called with a symbol representing the state.
|
132
|
+
Simply add a string/enum property called `state` to your DataMapper class, or
|
133
|
+
a `state` field to your ActiveRecord database and things should be fine. I
|
134
|
+
confess to having no familiarity with Sequel, but I don't foresee any
|
135
|
+
difficulty there either.
|
136
|
+
|
137
|
+
## License
|
138
|
+
|
139
|
+
SimpleState is released under the MIT License; see LICENSE for details.
|
140
|
+
|
141
|
+
[pluginaweek]: http://github.com/pluginaweek/state_machine (pluginaweek's state_machine library)
|
142
|
+
[rubyist]: http://github.com/rubyist/aasm (rubyist's aasm library)
|
143
|
+
[ryanallen]: http://github.com/ryan-allen/workflow (ryan-allen's Workflow library)
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anthonyw-simple_state
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anthony Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-09 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A *very simple* state machine implementation.
|
17
|
+
email: anthony@ninecraft.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.markdown
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- README.markdown
|
27
|
+
- LICENSE
|
28
|
+
has_rdoc: true
|
29
|
+
homepage: http://github.com/anthonyw/simple_state
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options:
|
32
|
+
- --inline-source
|
33
|
+
- --charset=UTF-8
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.2.0
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: A *very simple* state machine implementation.
|
55
|
+
test_files: []
|
56
|
+
|