davidlee-state-fu 0.11.1 → 0.12.0

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.textile CHANGED
@@ -1,49 +1,138 @@
1
- h1. State-Fu
1
+ h1. StateFu
2
2
 
3
3
  h2. What is it?
4
4
 
5
- State-Fu is:
5
+ StateFu is another Ruby state machine.
6
6
 
7
- * a generalized, extensible framework for state-oriented,
8
- event-driven programming in Ruby.
7
+ h2. What is a state machine?
9
8
 
10
- * a rich DSL for describing workflows, rules engines, behaviours and
11
- processes
9
+ Finite state machines are a model for program behaviour; like
10
+ object-oriented programming, they provide an abstract way to think
11
+ about a domain.
12
12
 
13
- * useful both as a Rails plugin, and in standalone ruby programs
14
- without any additional dependencies.
13
+ In a finite state machine, there are a number of discrete states. Only
14
+ one state may be occupied at any given time (hence the "finite").
15
15
 
16
- It lets you describe:
16
+ States are linked together by events, and there are rules which govern
17
+ when or how transitions between states can occur. Actions may be fired
18
+ on entry to or exit from a state, or when a certain transition occurs.
17
19
 
18
- * series of discrete states
20
+ h2. Why is StateFu different to the other twenty state machines for Ruby?
19
21
 
20
- * events which allow transitions to occur between states
22
+ State machines are potentially a powerful way to simplify and
23
+ structure a lot of problems. They can be used to:
21
24
 
22
- * rules (requirements) about when these transitions can occur
25
+ * succinctly define the grammar of a networking protocol or a
26
+ configuration DSL
23
27
 
24
- * behaviours which occur when they do
28
+ * clearly and compactly describe complex logic, which might otherwise
29
+ be difficult to understand by playing "follow the rabbit" through
30
+ methods thick with implementation details
25
31
 
26
- Which adds up to a surprisingly useful way to skin a lot of
27
- problems
32
+ * serialize and process multiple revisions of changing business rules
28
33
 
29
- Other libraries exist for ruby which do some or all of these
30
- things. "What's different about State-Fu?", you may ask.
34
+ * provide an abstract representation of program or domain behaviour
35
+ which can be introspected, edited, queried and executed on the fly,
36
+ in a high-level and human-readable format
31
37
 
32
- h2. Why StateFu is not your grandmother's state machine
38
+ * provide a straightforward and easy way to record and validate
39
+ "status" information, especially when there are rules governing
40
+ when and how it can be updated
33
41
 
34
- h3. Flippant answer:
42
+ * reduce proliferation of classes and modules, or easily define and
43
+ control functionally related groups of objects, by defining
44
+ behaviours on interacting components of a state machine
35
45
 
36
- Those libraries you've played with are toys. They're made of
37
- plastic. State-Fu is forged from a reassuringly dense but
38
- unidentifiable metal which comes only from the rarest of meteorites,
39
- and it ticks when you hold it up to your ear.[1]
46
+ * elegantly implement simple building blocks like stacks / queues,
47
+ parsers, schedulers, automata, etc
40
48
 
41
- State-Fu is elegant, powerful and transparent enough that you can use
49
+ StateFu was written from the ground up with one goal in mind: to be
50
+ over-engineered. It is designed to make truly ambitious use of state
51
+ machines not only viable, but strongly advantageous in many situations.
52
+
53
+ It is designed in the very opposite vein to the intentional minimalism
54
+ of most ruby state machine projects; it is tasked with taking on a
55
+ great deal of complexity and functionality, and abstracting it behind
56
+ a nice DSL, so that the code which *you* have to maintain is shorter and
57
+ clearer.
58
+
59
+ StateFu allows you to:
60
+
61
+ * give a class any number of machines
62
+
63
+ * define behaviours on state entry / exit; before, after or during
64
+ execution of a particular event; or before / after every transition
65
+ in a given machine
66
+
67
+ * give any object own its own private, "singleton" machines,
68
+ which are unique to that object and modifiable at runtime.
69
+
70
+ * create events with any number of origin or target states
71
+
72
+ * define and query guard conditions / transition requirements,
73
+ to establish rules about when a transition is valid
74
+
75
+ * use powerful reflection and logging capabilities to easily expose
76
+ and debug the operation of your machines
77
+
78
+ * automatically and unobtrusively define methods for querying each
79
+ state and event, and for firing transitions
80
+
81
+ * easily find out which transitions are valid at any given time
82
+
83
+ * generate descriptive, contextual messages when a transition is
84
+ invalid
85
+
86
+ * halt a transition during execution
87
+
88
+ * easily extend StateFu's DSL to match the problem domain
89
+
90
+ * fire transitions with a payload of arguments and program context,
91
+ which is available to guard conditions, event hooks, and
92
+ requirement messages when they are evaluated
93
+
94
+ * use a lovely, simple and flexible API which gives you plenty of
95
+ choices about how to describe your problem domain; choose (or
96
+ build) a programming style which suits the task at hand from an
97
+ expressive range of options
98
+
99
+ * store arbitrary meta-data on any component of StateFu - a simple
100
+ but extremely powerful tool for integration with almost anything.
101
+
102
+ * flexible and helpful logging out of the box - will use the Rails
103
+ logger if you're in a Rails project, or standalone logging to
104
+ STDOUT or a file. Configurable loglevel and message prefixes help
105
+ StateFu be a good citizen in a shared application log.
106
+
107
+ * automatically generate diagrams of state machines / workflows with graphviz
108
+
109
+ * use an ActiveRecord field for state persistence, or a regular
110
+ attribute - or use both, on the same class, for different
111
+ machines. If an appropriate ActiveRecord field exists for a
112
+ machine, it will be used. Otherwise, an attr_accessor will be used
113
+ (and created, if necessary).
114
+
115
+ * customising the persistence mechanism (eg to use a Rails session,
116
+ or a text file, or your choice of ORM) is usually as easy as
117
+ defining a getter and setter method for the persistence field, and
118
+ a rule about when to use it. If you want to use StateFu with a
119
+ persistence mechanism which is not yet supported, send me a message.
120
+
121
+ * StateFu is fast, lightweight and useful enough to use in any ruby
122
+ project - works with Rails but does not require it.
123
+
124
+ h2. Still not sold?
125
+
126
+ StateFu is forged from a reassuringly dense but unidentifiable metal
127
+ which comes only from the rarest of meteorites, and it ticks when you
128
+ hold it up to your ear.[1]
129
+
130
+ It is elegant, powerful and transparent enough that you can use
42
131
  it to drive substantial parts of your application, and actually want
43
132
  to do so.
44
133
 
45
134
  It is designed as a library for authors, as well as users, of
46
- libraries: State-Fu goes to great lengths to impose very few limits on
135
+ libraries: StateFu goes to great lengths to impose very few limits on
47
136
  your ability to introspect, manipulate and extend the core features.
48
137
 
49
138
  It is also delightfully elegant and easy to use for simple things:
@@ -97,124 +186,7 @@ It is also delightfully elegant and easy to use for simple things:
97
186
 
98
187
  </code></pre>
99
188
 
100
- h3. Feature Comparison and Detailed Answer
101
-
102
- A few of the features which set State-Fu apart for more ambitious work are:
103
-
104
- * a lovely, simple and flexible API gives you plenty of choices about
105
- how to describe your problem domain.
106
-
107
- * define any number of workflows on the same object / model;
108
- workflows (Machines) can be entirely separate, or interact with
109
- each other. Re-use machines across multiple classes, serialize them
110
- to a database, or build them on the fly.
111
-
112
- * events can transition from / to any number of states
113
-
114
- * drive application behaviour with a rich set of event hooks
115
-
116
- * define behaviour as methods on your objects, or keep it all in the
117
- state machine itself
118
-
119
- * requirements determine at runtime whether a particular state
120
- transition can occur, and if not, can tell a user (or developer)
121
- what they must do to satisfy the requirements.
122
-
123
- * requirement failure messages can be generated at runtime, making
124
- use of whatever application and state-machine context they need
125
-
126
- * transitions can be halted mid-execution, and you can actually
127
- determine why, and where from
128
-
129
- * in every event hook, requirement filter, and other method calls,
130
- you have complete and consistent access to your classes, its
131
- StateFu::Machines, and any Transition context. Use real ruby code
132
- anywhere, without breathing through a straw!
133
-
134
- * extend State-Fu (with Lathe#helper) Binding and Transition
135
- instances for your Machine to define your a DSL customized for your
136
- problem domain, and to keep your class definitions clean. Helper
137
- methods have easy access to all the context associated with your
138
- object instance, its StateFu::Machines and any Transition in
139
- progress.
140
-
141
- * extend a State-Fu Lathe (with Lathe#tool) to keep your Machine
142
- definitions DRY
143
-
144
- * store arbitrary meta-data on any component of State-Fu - a simple
145
- but extremely powerful tool for integration with almost anything.
146
-
147
- * designed for transparency, introspection and ease of debugging,
148
- which means a dynamic, powerful system you can actually use without
149
- headaches.
150
-
151
- * flexible and helpful logging out of the box - will use the Rails
152
- logger if you're in a Rails project, or standalone logging to
153
- STDOUT or a file. Configurable loglevel and message prefixes help
154
- StateFu be a good citizen in a shared application log.
155
-
156
- * magically generate diagrams of state machines / workflows with graphviz
157
-
158
- * "magically" use an ActiveRecord field for state persistence, or just an
159
- attribute - or use both, on the same class, for different
160
- workflows. If an ActiveRecord field exists for a machine's
161
- field_name (by default, the machine's name suffixed with '_field';
162
- the default machine name is 'state_fu', so if you don't explicitly
163
- name a machine it will look for 'state_fu_field' in your
164
- ActiveRecord columns (if ActiveRecord is included) and use
165
- that. Otherwise, an attr_accessor will be used (and created, if
166
- necessary).
167
-
168
- * customising the persistence mechanism (eg to use a Rails session,
169
- or a text file, or your choice of ORM) is usually as easy as
170
- defining a getter and setter method for the persistence field, and
171
- a rule about when to use it. If you want to use StateFu with a
172
- persistence mechanism which is not yet supported, I'd like to hear
173
- about it.
174
-
175
- * fast, lightweight and useful enough to use in any ruby
176
- project - works with Rails but does not require it.
177
-
178
- State-Fu works with any modern Ruby ( 1.8.6, 1.8.7, and 1.9.1)
179
-
180
- fn1. No disrespect intended to the authors of other similar libraries
181
- - some of whom I've borrowed an idea or two, and some useful criticism,
182
- from. They're stand-up guys, all of them. It's the truth though.
183
-
184
- I'd like to thank Ryan Allen in particular for his Workflow library,
185
- which I previously forked, piled hundreds of lines of code into and renamed
186
- Stateful (now deprecated). Some of his ideas (for example the ability to store metadata
187
- easily on *everything* ) have been instrumental in State-Fu's design.
188
-
189
- I'd also like to tip my hat at John Barnette, who's own
190
- (coincidentally named) Stateful set a very high standard with an
191
- exceptionally elegant API.
192
-
193
- h3. StateFu is not a complete BPM (Business Process Management) platform
194
-
195
- It's worth noting that StateFu is at it's core a state machine, which
196
- strives to be powerful enough to be able to drive many kinds of
197
- application behaviour.
198
-
199
- It is not, however, a "proper" workflow engine on par with Ruote. In
200
- StateFu the basic units with which "workflows" are built are states
201
- and events; Ruote takes a higher level view, dealing with processes
202
- and participants. As a result, it's capable of directly implementing
203
- these design patterns:
204
-
205
- http://openwferu.rubyforge.org/patterns.html
206
-
207
- Whereas StateFu cannot, for example, readily model forking / merging
208
- of processes (nor does it handles scheduling, process management, etc.
209
-
210
- The author of Ruote, the Ruby Workflow Engine, outlines the difference
211
- pretty clearly here:
212
-
213
- http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/
214
-
215
- If your application can be described with StateFu, you'll likely find
216
- it simpler to get running and work with; if not, you may find Ruote,
217
- or a combination of the two, suits your needs perfectly.
189
+ StateFu works with any modern Ruby ( 1.8.6, 1.8.7, and 1.9.1)
218
190
 
219
191
  h2. Getting started
220
192
 
@@ -276,6 +248,7 @@ dependent libraries.
276
248
  So if you plan to use ActiveSupport in a stand-alone project with
277
249
  StateFu, you should require it before StateFu.
278
250
 
251
+
279
252
  h3. Addditional Resources
280
253
 
281
254
  Also see the "issue tracker":http://github.com/davidlee/state-fu/issues
@@ -284,10 +257,36 @@ And the "build monitor":http://runcoderun.com/davidlee/state-fu/
284
257
 
285
258
  And the "RDoc":http://rdoc.info/projects/davidlee/state-fu
286
259
 
260
+
261
+ h3. StateFu is not a complete BPM (Business Process Management) platform
262
+
263
+ It's worth noting that StateFu is at it's core a state machine, which
264
+ strives to be powerful enough to be able to drive many kinds of
265
+ application behaviour.
266
+
267
+ It is not, however, a classical workflow engine on par with Ruote. In
268
+ StateFu the basic units with which "workflows" are built are states
269
+ and events; Ruote takes a higher level view, dealing with processes
270
+ and participants. As a result, it's capable of directly implementing
271
+ these design patterns:
272
+
273
+ http://openwferu.rubyforge.org/patterns.html
274
+
275
+ Whereas StateFu cannot, for example, readily model forking / merging
276
+ of processes (nor does it handles scheduling, process management, etc.
277
+
278
+ The author of Ruote, the Ruby Workflow Engine, outlines the difference
279
+ pretty clearly here:
280
+
281
+ http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/
282
+
283
+ If your application can be described with StateFu, you'll likely find
284
+ it simpler to get running and work with; if not, you may find Ruote,
285
+ or a combination of the two, suits your needs perfectly.
286
+
287
287
  h3. Thanks
288
288
 
289
- * dsturnbull, for helping w/ a patch to stop an error being raised
290
- when an activerecord model has no database table
289
+ * dsturnbull, for patches
291
290
 
292
291
  * lachie, benkimball for pointing out README bugs / typos
293
292
 
data/lib/binding.rb CHANGED
@@ -3,13 +3,12 @@ module StateFu
3
3
 
4
4
  attr_reader :object, :machine, :method_name, :field_name, :persister, :transitions, :options, :target
5
5
 
6
-
7
6
  # the constructor should not be called manually; a binding is
8
7
  # returned when an instance of a class with a StateFu::Machine
9
8
  # calls:
10
9
  #
11
10
  # instance.#state_fu (for the default machine which is called :state_fu),
12
- # instance.#state_fu( :<machine_name> ) ,or
11
+ # instance.#state_fu(:<machine_name>) ,or
13
12
  # instance.#<machine_name>
14
13
  #
15
14
  def initialize( machine, object, method_name, options={} )
@@ -18,13 +17,18 @@ module StateFu
18
17
  @method_name = method_name
19
18
  @transitions = []
20
19
  @options = options.symbolize_keys!
21
- @target = singleton? ? object : object.class
22
- @field_name = options[:field_name] || @target.state_fu_field_names[method_name]
23
- @persister = Persistence.for( self )
20
+ if options[:singleton]
21
+ @target = object
22
+ else
23
+ @target = object.class
24
+ @options = @target.state_fu_options[@method_name].merge(options)
25
+ end
26
+ @field_name = @options[:field_name] || raise("No field_name supplied in #{@options.inspect}")
27
+ @persister = Persistence.for self
24
28
 
25
29
  # define event methods on this binding and its @object
26
- MethodFactory.new( self ).install!
27
- @machine.helpers.inject_into( self )
30
+ MethodFactory.new(self).install!
31
+ @machine.helpers.inject_into self
28
32
  end
29
33
 
30
34
  alias_method :o, :object
@@ -60,26 +64,26 @@ module StateFu
60
64
 
61
65
  #
62
66
  # These methods are called from methods defined by MethodFactory.
63
- #
64
-
67
+ #
68
+
65
69
  # event_name [target], *args
66
70
  #
67
71
  def find_transition(event, target=nil, *args)
68
- target ||= args.last[:to].to_sym rescue nil
72
+ target ||= args.last[:to].to_sym rescue nil
69
73
  query = transitions.for_event(event).to(target).with(*args)
70
- query.find || query.valid.singular || nil
74
+ query.find || query.valid.singular || nil
71
75
  end
72
76
 
73
77
  # event_name? [target], *args
74
78
  #
75
79
  def can_transition?(event, target=nil, *args)
76
80
  begin
77
- if t = find_transition(event, target, *args)
81
+ if t = find_transition(event, target, *args)
78
82
  t.valid?(*args)
79
83
  end
80
84
  rescue IllegalTransition, UnknownTarget
81
85
  nil
82
- end
86
+ end
83
87
  end
84
88
 
85
89
  # event_name! [target], *args
@@ -100,7 +104,7 @@ module StateFu
100
104
  end
101
105
  alias_method :events_from_current_state, :events
102
106
 
103
- # all states which can be reached from the current_state.
107
+ # all states which can be reached from the current_state.
104
108
  # Does not check transition requirements, etc.
105
109
  def next_states
106
110
  events.map(&:targets).compact.flatten.uniq.extend StateArray
@@ -125,11 +129,11 @@ module StateFu
125
129
  def valid_events(*args)
126
130
  valid_transitions(*args).events
127
131
  end
128
-
132
+
129
133
  def invalid_events(*args)
130
134
  (events - valid_events(*args)).extend StateArray
131
135
  end
132
-
136
+
133
137
 
134
138
  # initializes a new Transition to the given destination, with the
135
139
  # given *args (to be passed to requirements and hooks).
@@ -139,17 +143,17 @@ module StateFu
139
143
  def transition( event_or_array, *args, &block )
140
144
  return transitions.with(*args, &block).find(event_or_array)
141
145
  end
142
-
146
+
143
147
  #
144
148
  # next_transition and friends: when there's exactly one valid move
145
149
  #
146
-
150
+
147
151
  # if there is exactly one legal & valid transition which can be fired with
148
152
  # the given (optional) arguments, return it.
149
153
  def next_transition( *args, &block )
150
154
  transitions.with(*args, &block).next
151
155
  end
152
-
156
+
153
157
  # as above but ignoring any transitions whose origin and target are the same
154
158
  def next_transition_excluding_cycles( *args, &block )
155
159
  transitions.not_cyclic.with(*args, &block).next
@@ -158,7 +162,7 @@ module StateFu
158
162
  # if there is exactly one state reachable via a transition which
159
163
  # is valid with the given optional arguments, return it.
160
164
  def next_state(*args, &block)
161
- transitions.with(*args, &block).next_state
165
+ transitions.with(*args, &block).next_state
162
166
  end
163
167
 
164
168
  # if there is exactly one event which is valid with the given
@@ -166,7 +170,7 @@ module StateFu
166
170
  def next_event( *args )
167
171
  transitions.with(*args, &block).next_event
168
172
  end
169
-
173
+
170
174
  # if there is a next_transition, create, fire & return it
171
175
  # otherwise raise an IllegalTransition
172
176
  def next!( *args, &block )
@@ -179,7 +183,7 @@ module StateFu
179
183
  alias_method :next_transition!, :next!
180
184
  alias_method :next_event!, :next!
181
185
  alias_method :next_state!, :next!
182
-
186
+
183
187
  # if there is a next_transition, return true / false depending on
184
188
  # whether its requirements are met
185
189
  # otherwise, nil
@@ -222,6 +226,14 @@ module StateFu
222
226
  end
223
227
  end
224
228
 
229
+ # next! without the raise if there's no next transition
230
+ # TODO SPECME
231
+ def update!( *args, &block )
232
+ if t = next_transition( *args, &block )
233
+ t.fire!
234
+ end
235
+ end
236
+
225
237
  #
226
238
  # misc
227
239
  #
@@ -260,7 +272,7 @@ module StateFu
260
272
  options[:singleton]
261
273
  end
262
274
 
263
- # SPECME DOCME OR KILLME
275
+ # SPECME DOCME OR KILLME
264
276
  def reload()
265
277
  if persister.is_a?( Persistence::ActiveRecord )
266
278
  object.reload
@@ -272,13 +284,13 @@ module StateFu
272
284
  def inspect
273
285
  s = self.to_s
274
286
  s = s[0,s.length-1]
275
- s << " object=#{object}"
276
- s << " current_state=#{current_state.to_sym.inspect rescue nil}"
277
- s << " events=#{events.map(&:to_sym).inspect rescue nil}"
278
- s << " machine=#{machine.to_s}"
287
+ s << " object=#{object}"
288
+ s << " current_state=#{current_state.to_sym.inspect rescue nil}"
289
+ s << " events=#{events.map(&:to_sym).inspect rescue nil}"
290
+ s << " machine=#{machine.to_s}"
279
291
  s << ">"
280
292
  s
281
293
  end
282
-
294
+
283
295
  end
284
296
  end
data/lib/event.rb CHANGED
@@ -65,7 +65,7 @@ module StateFu
65
65
  end
66
66
 
67
67
  def cycle?
68
- origin && origin == target
68
+ origin && (origin == target)
69
69
  end
70
70
 
71
71
  # *adds to* the origin states given a list of symbols / States
data/lib/executioner.rb CHANGED
@@ -3,17 +3,7 @@ module StateFu
3
3
  # delegator class for evaluation methods / procs in the context of
4
4
  # your object.
5
5
  #
6
-
7
- # There's a bug in ruby 1.8.x where lambda {}.arity == -1 instead of 0
8
- # To get around this, turn it into a proc if conditions are dangerous.
9
- def self.get_effective_arity
10
- if RUBY_VERSION[0,3] == "1.8" && proc.arity == -1
11
- proc.to_proc.arity
12
- else
13
- proc.arity
14
- end
15
- end
16
-
6
+
17
7
  class Executioner
18
8
 
19
9
  # give us a blank slate
@@ -29,8 +19,6 @@ module StateFu
29
19
  self
30
20
  end
31
21
 
32
- # delegate :self, :to => :__target__
33
-
34
22
  delegate :origin, :to => :transition, :prefix => true # transition_origin
35
23
  delegate :target, :to => :transition, :prefix => true # transition_target
36
24
  delegate :event, :to => :transition, :prefix => true # transition_event
@@ -45,10 +33,10 @@ module StateFu
45
33
 
46
34
  attr_reader :transition, :__target__, :__self__
47
35
 
48
- alias_method :t, :transition
49
- alias_method :current_transition, :transition
50
- alias_method :context, :transition
51
- alias_method :ctx, :transition
36
+ alias_method :t, :transition
37
+ alias_method :current_transition, :transition
38
+ alias_method :context, :transition
39
+ alias_method :ctx, :transition
52
40
 
53
41
  alias_method :arguments, :args
54
42
  alias_method :transition_arguments, :args
@@ -112,7 +100,7 @@ module StateFu
112
100
  private
113
101
 
114
102
  # Forwards any missing method call to the \target.
115
- # TODO / FIXME / NOTE: we don't (can't ?) handle block arguments ...
103
+ # TODO / NOTE: we don't (can't ?) handle block arguments ...
116
104
  def method_missing(method_name, *args)
117
105
  if __target__.respond_to?(method_name, true)
118
106
  begin
@@ -126,13 +114,7 @@ module StateFu
126
114
  end
127
115
 
128
116
  end
129
-
130
- # # Forwards any missing constant references to the \target.
131
- # def self.const_missing(const_name)
132
- # unless __target__.class.const_defined?(const_name, true)
133
- # super(const_name)
134
- # end
135
- # __target__.class.const_get(const_name)
136
- # end
117
+
118
+ # NOTE: const_missing is not handled.
137
119
  end
138
120
  end
data/lib/interface.rb CHANGED
@@ -2,21 +2,19 @@ module StateFu
2
2
  module Interface
3
3
  module SoftAlias
4
4
 
5
- # define aliases that won't clobber existing methods -
6
- # so we can be liberal with them.
7
- def soft_alias(x)
8
- aliases = [ x.to_a[0] ].flatten
9
- original = aliases.shift
5
+ def soft_alias(hash)
10
6
  existing_method_names = (self.instance_methods | self.protected_instance_methods | self.private_instance_methods).map(&:to_sym)
11
- taken, ok = aliases.partition { |a| existing_method_names.include?(a.to_sym) }
12
- StateFu::Logger.debug("#{self.to_s} alias for ## #{original} already taken: #{taken.inspect}") unless taken.empty?
13
- ok.each { |a| alias_method a, original}
14
- end
15
-
7
+ hash.each do |original, aliases|
8
+ aliases.
9
+ reject { |a| existing_method_names.include?(a.to_sym) }.
10
+ each { |a| alias_method a, original}
11
+ end
12
+ end
16
13
  end
17
14
 
18
15
  module Aliases
19
-
16
+ # define aliases that won't clobber existing methods -
17
+ # so we can be liberal with them.
20
18
  def self.extended(base)
21
19
  base.extend SoftAlias
22
20
  base.class_eval do
@@ -70,8 +68,8 @@ module StateFu
70
68
  end
71
69
  alias_method :machine, :state_fu_machine
72
70
 
73
- def state_fu_field_names
74
- @_state_fu_field_names ||= {}
71
+ def state_fu_options
72
+ @_state_fu_options ||= {}
75
73
  end
76
74
 
77
75
  def state_fu_machines
@@ -97,7 +95,7 @@ module StateFu
97
95
  # can access a StateFu::Machine, the object's current state, the
98
96
  # methods which trigger event transitions, etc.
99
97
 
100
- def state_fu_binding( name = DEFAULT )
98
+ def state_fu_binding(name = DEFAULT)
101
99
  name = name.to_sym
102
100
  if machine = self.class.state_fu_machines[name]
103
101
  state_fu_bindings[name] ||= StateFu::Binding.new( machine, self, name )