Class: StateFu::Binding
Instance Attribute Summary (collapse)
-
- (Object) field_name
readonly
Returns the value of attribute field_name.
-
- (Object) machine
(also: #workflow, #state_machine)
readonly
Returns the value of attribute machine.
-
- (Object) method_name
readonly
Returns the value of attribute method_name.
-
- (Object) object
(also: #o, #obj, #model, #instance)
readonly
Returns the value of attribute object.
-
- (Object) options
readonly
Returns the value of attribute options.
-
- (Object) persister
readonly
Returns the value of attribute persister.
-
- (Object) target
readonly
Returns the value of attribute target.
-
- (Object) transitions(opts = {})
readonly
transition validation.
Instance Method Summary (collapse)
-
- (Object) ==(other)
let's be == (and hence ===) the current_state_name as a symbol.
-
- (Boolean) can_transition?(event, target = nil, *args)
event_name? [target], *args.
-
- (Object) current_state
(also: #now, #state)
the current State.
-
- (Object) current_state_name
(also: #name, #state_name, #to_sym)
the name, as a Symbol, of the binding's current_state.
-
- (Object) cycle(event_or_array = nil, *args, &block)
if there is one possible cyclical event, return a transition there otherwise, maybe we got an event name as an argument?.
-
- (Object) cycle!(event_or_array = nil, *args, &block)
if there is a single possible cycle() transition, fire and return it otherwise raise an IllegalTransition.
-
- (Boolean) cycle?(event_or_array = nil, *args)
if there is one possible cyclical event, evaluate its requirements (true/false), else nil.
-
- (Object) events
(also: #events_from_current_state)
returns a list of Events which can fire from the current_state.
-
- (Object) find_transition(event, target = nil, *args)
event_name [target], *args.
-
- (Object) fire_transition!(event, target = nil, *args)
event_name! [target], *args.
-
- (Binding) initialize(machine, object, method_name, options = {})
constructor
the constructor should not be called manually; a binding is returned when an instance of a class with a StateFu::Machine calls:.
-
- (Object) inspect
display something sensible that doesn't take up the whole screen.
- - (Object) invalid_events(*args)
-
- (Object) next!(*args, &block)
(also: #next_transition!, #next_event!, #next_state!)
if there is a next_transition, create, fire & return it otherwise raise an IllegalTransition.
-
- (Boolean) next?(*args, &block)
if there is a next_transition, return true / false depending on whether its requirements are met otherwise, nil.
-
- (Object) next_event(*args)
if there is exactly one event which is valid with the given optional arguments, return it.
-
- (Object) next_state(*args, &block)
if there is exactly one state reachable via a transition which is valid with the given optional arguments, return it.
-
- (Object) next_states
all states which can be reached from the current_state.
-
- (Object) next_transition(*args, &block)
if there is exactly one legal & valid transition which can be fired with the given (optional) arguments, return it.
-
- (Object) next_transition_excluding_cycles(*args, &block)
as above but ignoring any transitions whose origin and target are the same.
-
- (Object) reload
SPECME DOCME OR KILLME.
-
- (Boolean) singleton?
TODO better name is this a binding unique to a specific instance (not bound to a class)?.
-
- (Object) state_fu(name = nil)
little kludge - allows the binding to reuse the same method definitions as 'object' in MethodFactory#method_definitions_for.
-
- (Object) teleport!(target)
change the current state of the binding without any requirements or other sanity checks, or any hooks firing.
-
- (Object) transition(event_or_array, *args, &block)
initializes a new Transition to the given destination, with the given *args (to be passed to requirements and hooks).
-
- (Object) update!(*args, &block)
next! without the raise if there's no next transition TODO SPECME.
- - (Object) valid_events(*args)
- - (Object) valid_next_states(*args)
- - (Object) valid_transitions(*args)
Constructor Details
- (Binding) initialize(machine, object, method_name, options = {})
the constructor should not be called manually; a binding is returned when an instance of a class with a StateFu::Machine calls:
instance.#state_fu (for the default machine which is called :state_fu), instance.#state_fu(:<machine_name>) ,or instance.#<machine_name>
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/binding.rb', line 14 def initialize( machine, object, method_name, ={} ) @machine = machine @object = object @method_name = method_name @transitions = [] @options = .symbolize_keys! if [:singleton] @target = object else @target = object.class @options = @target.[@method_name].merge() end @field_name = @options.delete(:field_name) || raise("No field_name supplied") @persister = Persistence.for self # define event methods on this binding and its @object MethodFactory.new(self).install! @machine.helpers.inject_into self end |
Instance Attribute Details
- (Object) field_name (readonly)
Returns the value of attribute field_name
4 5 6 |
# File 'lib/binding.rb', line 4 def field_name @field_name end |
- (Object) machine (readonly) Also known as: workflow, state_machine
Returns the value of attribute machine
4 5 6 |
# File 'lib/binding.rb', line 4 def machine @machine end |
- (Object) method_name (readonly)
Returns the value of attribute method_name
4 5 6 |
# File 'lib/binding.rb', line 4 def method_name @method_name end |
- (Object) object (readonly) Also known as: o, obj, model, instance
Returns the value of attribute object
4 5 6 |
# File 'lib/binding.rb', line 4 def object @object end |
- (Object) options (readonly)
Returns the value of attribute options
4 5 6 |
# File 'lib/binding.rb', line 4 def @options end |
- (Object) persister (readonly)
Returns the value of attribute persister
4 5 6 |
# File 'lib/binding.rb', line 4 def persister @persister end |
- (Object) target (readonly)
Returns the value of attribute target
4 5 6 |
# File 'lib/binding.rb', line 4 def target @target end |
- (Object) transitions(opts = {}) (readonly)
transition validation
117 118 119 |
# File 'lib/binding.rb', line 117 def transitions @transitions end |
Instance Method Details
- (Object) ==(other)
let's be == (and hence ===) the current_state_name as a symbol. a nice little convenience.
260 261 262 263 264 265 266 |
# File 'lib/binding.rb', line 260 def == other if other.respond_to?( :to_sym ) && current_state current_state_name == other.to_sym || super( other ) else super( other ) end end |
- (Boolean) can_transition?(event, target = nil, *args)
event_name? [target], *args
79 80 81 82 83 84 85 86 87 |
# File 'lib/binding.rb', line 79 def can_transition?(event, target=nil, *args) begin if t = find_transition(event, target, *args) t.valid?(*args) end rescue IllegalTransition, UnknownTarget nil end end |
- (Object) current_state Also known as: now, state
the current State
47 48 49 |
# File 'lib/binding.rb', line 47 def current_state persister.current_state end |
- (Object) current_state_name Also known as: name, state_name, to_sym
the name, as a Symbol, of the binding's current_state
54 55 56 57 58 59 60 |
# File 'lib/binding.rb', line 54 def current_state_name begin current_state.name.to_sym rescue NoMethodError nil end end |
- (Object) cycle(event_or_array = nil, *args, &block)
if there is one possible cyclical event, return a transition there otherwise, maybe we got an event name as an argument?
201 202 203 204 205 206 207 208 |
# File 'lib/binding.rb', line 201 def cycle(event_or_array=nil, *args, &block) if event_or_array.nil? transitions.cyclic.with(*args, &block).singular || transitions.cyclic.with(*args, &block).valid.singular else transitions.cyclic.with(*args, &block).find(event_or_array) end end |
- (Object) cycle!(event_or_array = nil, *args, &block)
if there is a single possible cycle() transition, fire and return it otherwise raise an IllegalTransition
212 213 214 215 216 217 218 |
# File 'lib/binding.rb', line 212 def cycle!(event_or_array=nil, *args, &block ) returning cycle(event_or_array, *args, &block ) do |t| raise TransitionNotFound.new( self, transitions.cyclic.with(*args,&block), "Cannot cycle! unless there is exactly one cyclic event") \ if t.nil? t.fire! end end |
- (Boolean) cycle?(event_or_array = nil, *args)
if there is one possible cyclical event, evaluate its requirements (true/false), else nil
222 223 224 225 226 |
# File 'lib/binding.rb', line 222 def cycle?(event_or_array=nil, *args ) if t = cycle(event_or_array, *args ) t.requirements_met? end end |
- (Object) events Also known as: events_from_current_state
returns a list of Events which can fire from the current_state
100 101 102 103 104 |
# File 'lib/binding.rb', line 100 def events machine.events.select do |e| e.can_transition_from? current_state end.extend EventArray end |
- (Object) find_transition(event, target = nil, *args)
event_name [target], *args
71 72 73 74 75 |
# File 'lib/binding.rb', line 71 def find_transition(event, target=nil, *args) target ||= args.last[:to].to_sym rescue nil query = transitions.for_event(event).to(target).with(*args) query.find || query.valid.singular || nil end |
- (Object) fire_transition!(event, target = nil, *args)
event_name! [target], *args
91 92 93 |
# File 'lib/binding.rb', line 91 def fire_transition!(event, target=nil, *args) find_transition(event, target, *args).fire! end |
- (Object) inspect
display something sensible that doesn't take up the whole screen
248 249 250 251 252 253 254 255 256 |
# File 'lib/binding.rb', line 248 def inspect '<#' + self.class.to_s + ' ' + attrs = [[:current_state, state_name.inspect], [:object_type , @object.class], [:method_name , method_name.inspect], [:field_name , field_name.inspect], [:machine , machine.to_s]]. map {|x| x.join('=') }.join( " " ) + '>' end |
- (Object) invalid_events(*args)
133 134 135 |
# File 'lib/binding.rb', line 133 def invalid_events(*args) (events - valid_events(*args)).extend StateArray end |
- (Object) next!(*args, &block) Also known as: next_transition!, next_event!, next_state!
if there is a next_transition, create, fire & return it otherwise raise an IllegalTransition
175 176 177 178 179 180 181 |
# File 'lib/binding.rb', line 175 def next!( *args, &block ) if t = next_transition( *args, &block ) t.fire! else raise TransitionNotFound.new( self, valid_transitions(*args), "Exactly 1 valid transition required.") end end |
- (Boolean) next?(*args, &block)
if there is a next_transition, return true / false depending on whether its requirements are met otherwise, nil
189 190 191 192 193 |
# File 'lib/binding.rb', line 189 def next?( *args, &block ) if t = next_transition( *args, &block ) t.requirements_met? end end |
- (Object) next_event(*args)
if there is exactly one event which is valid with the given optional arguments, return it
169 170 171 |
# File 'lib/binding.rb', line 169 def next_event( *args ) transitions.with(*args, &block).next_event end |
- (Object) next_state(*args, &block)
if there is exactly one state reachable via a transition which is valid with the given optional arguments, return it.
163 164 165 |
# File 'lib/binding.rb', line 163 def next_state(*args, &block) transitions.with(*args, &block).next_state end |
- (Object) next_states
all states which can be reached from the current_state. Does not check transition requirements, etc.
109 110 111 |
# File 'lib/binding.rb', line 109 def next_states events.map(&:targets).compact.flatten.uniq.extend StateArray end |
- (Object) next_transition(*args, &block)
if there is exactly one legal & valid transition which can be fired with the given (optional) arguments, return it.
152 153 154 |
# File 'lib/binding.rb', line 152 def next_transition( *args, &block ) transitions.with(*args, &block).next end |
- (Object) next_transition_excluding_cycles(*args, &block)
as above but ignoring any transitions whose origin and target are the same
157 158 159 |
# File 'lib/binding.rb', line 157 def next_transition_excluding_cycles( *args, &block ) transitions.not_cyclic.with(*args, &block).next end |
- (Object) reload
SPECME DOCME OR KILLME
275 276 277 278 279 280 281 |
# File 'lib/binding.rb', line 275 def reload() if persister.is_a?( Persistence::ActiveRecord ) object.reload end persister.reload self end |
- (Boolean) singleton?
TODO better name is this a binding unique to a specific instance (not bound to a class)?
270 271 272 |
# File 'lib/binding.rb', line 270 def singleton? [:singleton] end |
- (Object) state_fu(name = nil)
little kludge - allows the binding to reuse the same method definitions as 'object' in MethodFactory#method_definitions_for
296 297 298 |
# File 'lib/binding.rb', line 296 def state_fu(name=nil) self end |
- (Object) teleport!(target)
change the current state of the binding without any requirements or other sanity checks, or any hooks firing. Useful for test / spec scenarios, and abusing the framework.
243 244 245 |
# File 'lib/binding.rb', line 243 def teleport!( target ) persister.current_state=( machine.states[target] ) end |
- (Object) transition(event_or_array, *args, &block)
initializes a new Transition to the given destination, with the given *args (to be passed to requirements and hooks).
If a block is given, it yields the Transition or is executed in its evaluation context, depending on the arity of the block.
143 144 145 |
# File 'lib/binding.rb', line 143 def transition( event_or_array, *args, &block ) return transitions.with(*args, &block).find(event_or_array) end |
- (Object) update!(*args, &block)
next! without the raise if there's no next transition TODO SPECME
230 231 232 233 234 |
# File 'lib/binding.rb', line 230 def update!( *args, &block ) if t = next_transition( *args, &block ) t.fire! end end |
- (Object) valid_events(*args)
129 130 131 |
# File 'lib/binding.rb', line 129 def valid_events(*args) valid_transitions(*args).events end |
- (Object) valid_next_states(*args)
125 126 127 |
# File 'lib/binding.rb', line 125 def valid_next_states(*args) valid_transitions(*args).targets end |
- (Object) valid_transitions(*args)
121 122 123 |
# File 'lib/binding.rb', line 121 def valid_transitions(*args) transitions.valid.with(*args) end |