Class: StateMachine::Callback
- Inherits:
-
Object
- Object
- StateMachine::Callback
- Includes:
- EvalHelpers
- Defined in:
- lib/state_machine/callback.rb
Overview
Callbacks represent hooks into objects that allow logic to be triggered before or after a specific transition occurs.
Class Attribute Summary collapse
-
.bind_to_object ⇒ Object
Determines whether to automatically bind the callback to the object being transitioned.
-
.terminator ⇒ Object
The application-wide terminator to use for callbacks when not explicitly defined.
Instance Attribute Summary collapse
-
#guard ⇒ Object
readonly
The guard that determines whether or not this callback can be invoked based on the context of the transition.
-
#terminator ⇒ Object
readonly
An optional block for determining whether to cancel the callback chain based on the return value of the callback.
Instance Method Summary collapse
-
#call(object, context = {}, *args) ⇒ Object
Runs the callback as long as the transition context matches the guard requirements configured for this callback.
-
#initialize(*args, &block) ⇒ Callback
constructor
Creates a new callback that can get called based on the configured options.
-
#known_states ⇒ Object
Gets a list of the states known to this callback by looking at the guard’s known states.
Methods included from EvalHelpers
Constructor Details
#initialize(*args, &block) ⇒ Callback
Creates a new callback that can get called based on the configured options.
In addition to the possible configuration options for guards, the following options can be configured:
-
:bind_to_object- Whether to bind the callback to the object involved. If set to false, the object will be passed as a parameter instead. Default is integration-specific or set to the application default. -
:terminator- A block/proc that determines what callback results should cause the callback chain to halt (if not using the defaultthrow :halttechnique).
More information about how those options affect the behavior of the callback can be found in their attribute definitions.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/state_machine/callback.rb', line 115 def initialize(*args, &block) = args.last.is_a?(Hash) ? args.pop : {} @methods = args @methods.concat(Array(.delete(:do))) @methods << block if block_given? raise ArgumentError, 'Method(s) for callback must be specified' unless @methods.any? = {:bind_to_object => self.class.bind_to_object, :terminator => self.class.terminator}.merge() # Proxy lambda blocks so that they're bound to the object bind_to_object = .delete(:bind_to_object) @methods.map! do |method| bind_to_object && method.is_a?(Proc) ? bound_method(method) : method end @terminator = .delete(:terminator) @guard = Guard.new() end |
Class Attribute Details
.bind_to_object ⇒ Object
Determines whether to automatically bind the callback to the object being transitioned. This only applies to callbacks that are defined as lambda blocks (or Procs). Some integrations, such as DataMapper, handle callbacks by executing them bound to the object involved, while other integrations, such as ActiveRecord, pass the object as an argument to the callback. This can be configured on an application-wide basis by setting this configuration to true or false. The default value is false.
Note that the DataMapper and Sequel integrations automatically configure this value on a per-callback basis, so it does not have to be enabled application-wide.
Examples
When not bound to the object:
class Vehicle
state_machine do
before_transition do |vehicle|
vehicle.set_alarm
end
end
def set_alarm
...
end
end
When bound to the object:
StateMachine::Callback.bind_to_object = true
class Vehicle
state_machine do
before_transition do
self.set_alarm
end
end
def set_alarm
...
end
end
55 56 57 |
# File 'lib/state_machine/callback.rb', line 55 def bind_to_object @bind_to_object end |
.terminator ⇒ Object
The application-wide terminator to use for callbacks when not explicitly defined. Terminators determine whether to cancel a callback chain based on the return value of the callback.
See StateMachine::Callback#terminator for more information.
62 63 64 |
# File 'lib/state_machine/callback.rb', line 62 def terminator @terminator end |
Instance Attribute Details
#guard ⇒ Object (readonly)
The guard that determines whether or not this callback can be invoked based on the context of the transition. The event, from state, and to state must all match in order for the guard to pass.
See StateMachine::Guard for more information.
99 100 101 |
# File 'lib/state_machine/callback.rb', line 99 def guard @guard end |
#terminator ⇒ Object (readonly)
An optional block for determining whether to cancel the callback chain based on the return value of the callback. By default, the callback chain never cancels based on the return value (i.e. there is no implicit terminator). Certain integrations, such as ActiveRecord and Sequel, change this default value.
Examples
Canceling the callback chain without a terminator:
class Vehicle
state_machine do
before_transition do |vehicle|
throw :halt
end
end
end
Canceling the callback chain with a terminator value of false:
class Vehicle
state_machine do
before_transition do |vehicle|
false
end
end
end
92 93 94 |
# File 'lib/state_machine/callback.rb', line 92 def terminator @terminator end |
Instance Method Details
#call(object, context = {}, *args) ⇒ Object
Runs the callback as long as the transition context matches the guard requirements configured for this callback.
If a terminator has been configured and it matches the result from the evaluated method, then the callback chain should be halted.
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/state_machine/callback.rb', line 146 def call(object, context = {}, *args) if @guard.matches?(object, context) @methods.each do |method| result = evaluate_method(object, method, *args) throw :halt if @terminator && @terminator.call(result) end true else false end end |
#known_states ⇒ Object
Gets a list of the states known to this callback by looking at the guard’s known states
137 138 139 |
# File 'lib/state_machine/callback.rb', line 137 def known_states guard.known_states end |