Class: StateMachines::Branch
- Inherits:
-
Object
- Object
- StateMachines::Branch
- Includes:
- EvalHelpers
- Defined in:
- lib/state_machines/branch.rb
Overview
Represents a set of requirements that must be met in order for a transition or callback to occur. Branches verify that the event, from state, and to state of the transition match, in addition to if/unless conditionals for an object’s state.
Instance Attribute Summary collapse
-
#event_requirement ⇒ Object
readonly
The requirement for verifying the event being matched.
-
#if_condition ⇒ Object
readonly
The condition that must be met on an object.
-
#known_states ⇒ Object
readonly
A list of all of the states known to this branch.
-
#state_requirements ⇒ Object
readonly
One or more requirements for verifying the states being matched.
-
#unless_condition ⇒ Object
readonly
The condition that must not be met on an object.
Instance Method Summary collapse
- #draw(graph, event, valid_states, io = $stdout) ⇒ Object
-
#initialize(options = {}) ⇒ Branch
constructor
Creates a new branch.
-
#match(object, query = {}, event_args = []) ⇒ Object
Attempts to match the given object / query against the set of requirements configured for this branch.
-
#matches?(object, query = {}) ⇒ Boolean
Determines whether the given object / query matches the requirements configured for this branch.
Methods included from EvalHelpers
#evaluate_method, #evaluate_method_with_event_args
Constructor Details
#initialize(options = {}) ⇒ Branch
Creates a new branch
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/state_machines/branch.rb', line 33 def initialize( = {}) # :nodoc: # Build conditionals @if_condition = .delete(:if) @unless_condition = .delete(:unless) # Build event requirement @event_requirement = build_matcher(, :on, :except_on) if (.keys - %i[from to on except_from except_to except_on]).empty? # Explicit from/to requirements specified @state_requirements = [{ from: build_matcher(, :from, :except_from), to: build_matcher(, :to, :except_to) }] else # Separate out the event requirement .delete(:on) .delete(:except_on) # Implicit from/to requirements specified @state_requirements = .collect do |from, to| from = WhitelistMatcher.new(from) unless from.is_a?(Matcher) to = WhitelistMatcher.new(to) unless to.is_a?(Matcher) { from: from, to: to } end end # Track known states. The order that requirements are iterated is based # on the priority in which tracked states should be added. @known_states = [] @state_requirements.each do |state_requirement| %i[from to].each { |option| @known_states |= state_requirement[option].values } end end |
Instance Attribute Details
#event_requirement ⇒ Object (readonly)
The requirement for verifying the event being matched
20 21 22 |
# File 'lib/state_machines/branch.rb', line 20 def event_requirement @event_requirement end |
#if_condition ⇒ Object (readonly)
The condition that must be met on an object
14 15 16 |
# File 'lib/state_machines/branch.rb', line 14 def if_condition @if_condition end |
#known_states ⇒ Object (readonly)
A list of all of the states known to this branch. This will pull states from the following options (in the same order):
-
from
/except_from
-
to
/except_to
30 31 32 |
# File 'lib/state_machines/branch.rb', line 30 def known_states @known_states end |
#state_requirements ⇒ Object (readonly)
One or more requirements for verifying the states being matched. All requirements contain a mapping of => matcher, :to => matcher.
24 25 26 |
# File 'lib/state_machines/branch.rb', line 24 def state_requirements @state_requirements end |
#unless_condition ⇒ Object (readonly)
The condition that must not be met on an object
17 18 19 |
# File 'lib/state_machines/branch.rb', line 17 def unless_condition @unless_condition end |
Instance Method Details
#draw(graph, event, valid_states, io = $stdout) ⇒ Object
127 128 129 |
# File 'lib/state_machines/branch.rb', line 127 def draw(graph, event, valid_states, io = $stdout) machine.renderer.draw_branch(self, graph, event, valid_states, io) end |
#match(object, query = {}, event_args = []) ⇒ Object
Attempts to match the given object / query against the set of requirements configured for this branch. In addition to matching the event, from state, and to state, this will also check whether the configured :if/:unless conditions pass on the given object.
If a match is found, then the event/state requirements that the query passed successfully will be returned. Otherwise, nil is returned if there was no match.
Query options:
-
:from
- One or more states being transitioned from. If none are specified, then this will always match. -
:to
- One or more states being transitioned to. If none are specified, then this will always match. -
:on
- One or more events that fired the transition. If none are specified, then this will always match. -
:guard
- Whether to guard matches with the if/unless conditionals defined for this branch. Default is true.
Event arguments are passed to guard conditions if they accept multiple parameters.
Examples
branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
branch.match(object, :on => :park) # => nil
119 120 121 122 123 124 125 |
# File 'lib/state_machines/branch.rb', line 119 def match(object, query = {}, event_args = []) StateMachines::OptionsValidator.assert_valid_keys!(query, :from, :to, :on, :guard) return unless (match = match_query(query)) && matches_conditions?(object, query, event_args) match end |
#matches?(object, query = {}) ⇒ Boolean
Determines whether the given object / query matches the requirements configured for this branch. In addition to matching the event, from state, and to state, this will also check whether the configured :if/:unless conditions pass on the given object.
Examples
branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
# Successful
branch.matches?(object, :on => :ignite) # => true
branch.matches?(object, :from => nil) # => true
branch.matches?(object, :from => :parked) # => true
branch.matches?(object, :to => :idling) # => true
branch.matches?(object, :from => :parked, :to => :idling) # => true
branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
# Unsuccessful
branch.matches?(object, :on => :park) # => false
branch.matches?(object, :from => :idling) # => false
branch.matches?(object, :to => :first_gear) # => false
branch.matches?(object, :from => :parked, :to => :first_gear) # => false
branch.matches?(object, :on => :park, :from => :parked, :to => :idling) # => false
88 89 90 |
# File 'lib/state_machines/branch.rb', line 88 def matches?(object, query = {}) !match(object, query).nil? end |