diff --git a/Gemfile b/Gemfile
index f9c6782..3689b8e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,4 +11,5 @@ group :development do
gem "rubocop-shopify"
gem "rubocop-sorbet"
gem "rails", "~> 7.2"
+ gem "state_machines"
end
diff --git a/Gemfile.lock b/Gemfile.lock
index acce072..c5aa5ae 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- boba (0.0.9)
+ boba (0.0.11)
sorbet-static-and-runtime (~> 0.5)
tapioca (~> 0.16.4)
@@ -223,6 +223,7 @@ GEM
prism (>= 0.28.0)
sorbet-static-and-runtime (>= 0.5.10187)
thor (>= 0.19.2)
+ state_machines (0.6.0)
stringio (3.1.1)
tapioca (0.16.4)
bundler (>= 2.2.25)
@@ -259,6 +260,7 @@ DEPENDENCIES
rubocop-rspec
rubocop-shopify
rubocop-sorbet
+ state_machines
RUBY VERSION
ruby 3.3.6p108
diff --git a/History.md b/History.md
index 5d65ce6..a09f1f3 100644
--- a/History.md
+++ b/History.md
@@ -1,5 +1,10 @@
# Boba History
+## 0.0.11
+
+- Dupe Tapioca `StateMachines` compiler and fix bug with abstract classes and preloading instance methods.
+- Fix sorting bug in `Paperclip` compiler.
+
## 0.0.10
- Handle abstract classes in `StateMachinesExtended` better
diff --git a/lib/boba/version.rb b/lib/boba/version.rb
index b4673fc..d4bf1c7 100644
--- a/lib/boba/version.rb
+++ b/lib/boba/version.rb
@@ -2,5 +2,5 @@
# frozen_string_literal: true
module Boba
- VERSION = "0.0.9"
+ VERSION = "0.0.11"
end
diff --git a/lib/tapioca/dsl/compilers/paperclip.rb b/lib/tapioca/dsl/compilers/paperclip.rb
index 491af62..1567c23 100644
--- a/lib/tapioca/dsl/compilers/paperclip.rb
+++ b/lib/tapioca/dsl/compilers/paperclip.rb
@@ -49,7 +49,9 @@ def gather_constants
sig { override.void }
def decorate
- attachments = ::Paperclip::AttachmentRegistry.names_for(constant)
+ # this is a bit awkward, but load order determines the return order here, so sort to ensure consistency across
+ # all environments.
+ attachments = ::Paperclip::AttachmentRegistry.names_for(constant).sort
return if attachments.empty?
root.create_path(constant) do |klass|
diff --git a/lib/tapioca/dsl/compilers/state_machines.rb b/lib/tapioca/dsl/compilers/state_machines.rb
new file mode 100644
index 0000000..de1314d
--- /dev/null
+++ b/lib/tapioca/dsl/compilers/state_machines.rb
@@ -0,0 +1,385 @@
+# typed: strict
+# frozen_string_literal: true
+
+return unless defined?(StateMachines)
+
+require "tapioca/dsl/helpers/active_record_constants_helper"
+
+module Tapioca
+ module Dsl
+ module Compilers
+ # `Tapioca::Dsl::Compilers::StateMachines` generates RBI files for classes that setup a
+ # [`state_machine`](https://github.com/state-machines/state_machines). The compiler also
+ # processes the extra methods generated by
+ # [StateMachines Active Record](https://github.com/state-machines/state_machines-activerecord)
+ # and [StateMachines Active Model](https://github.com/state-machines/state_machines-activemodel)
+ # integrations.
+ #
+ # For example, with the following `Vehicle` class:
+ #
+ # ~~~rb
+ # class Vehicle
+ # state_machine :alarm_state, initial: :active, namespace: :'alarm' do
+ # event :enable do
+ # transition all => :active
+ # end
+ #
+ # event :disable do
+ # transition all => :off
+ # end
+ #
+ # state :active, :value => 1
+ # state :off, :value => 0
+ # end
+ # end
+ # ~~~
+ #
+ # this compiler will produce the RBI file `vehicle.rbi` with the following content:
+ #
+ # ~~~rbi
+ # # vehicle.rbi
+ # # typed: true
+ # class Vehicle
+ # include StateMachineInstanceHelperModule
+ # extend StateMachineClassHelperModule
+ #
+ # module StateMachineClassHelperModule
+ # sig { params(event: T.any(String, Symbol)).returns(String) }
+ # def human_alarm_state_event_name(event); end
+ #
+ # sig { params(state: T.any(String, Symbol)).returns(String) }
+ # def human_alarm_state_name(state); end
+ # end
+ #
+ # module StateMachineInstanceHelperModule
+ # sig { returns(T::Boolean) }
+ # def alarm_active?; end
+ #
+ # sig { returns(T::Boolean) }
+ # def alarm_off?; end
+ #
+ # sig { returns(Integer) }
+ # def alarm_state; end
+ #
+ # sig { params(value: Integer).returns(Integer) }
+ # def alarm_state=(value); end
+ #
+ # sig { params(state: T.any(String, Symbol)).returns(T::Boolean) }
+ # def alarm_state?(state); end
+ #
+ # sig { params(args: T.untyped).returns(T::Array[T.any(String, Symbol)]) }
+ # def alarm_state_events(*args); end
+ #
+ # sig { returns(T.any(String, Symbol)) }
+ # def alarm_state_name; end
+ #
+ # sig { params(args: T.untyped).returns(T::Array[::StateMachines::Transition]) }
+ # def alarm_state_paths(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T::Array[::StateMachines::Transition]) }
+ # def alarm_state_transitions(*args); end
+ #
+ # sig { returns(T::Boolean) }
+ # def can_disable_alarm?; end
+ #
+ # sig { returns(T::Boolean) }
+ # def can_enable_alarm?; end
+ #
+ # sig { params(args: T.untyped).returns(T::Boolean) }
+ # def disable_alarm(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T::Boolean) }
+ # def disable_alarm!(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T.nilable(::StateMachines::Transition)) }
+ # def disable_alarm_transition(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T::Boolean) }
+ # def enable_alarm(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T::Boolean) }
+ # def enable_alarm!(*args); end
+ #
+ # sig { params(args: T.untyped).returns(T.nilable(::StateMachines::Transition)) }
+ # def enable_alarm_transition(*args); end
+ #
+ # sig { params(event: T.any(String, Symbol), args: T.untyped).returns(T::Boolean) }
+ # def fire_alarm_state_event(event, *args); end
+ #
+ # sig { returns(String) }
+ # def human_alarm_state_name; end
+ # end
+ # end
+ # ~~~
+ class StateMachines < Compiler
+ extend T::Sig
+
+ ACTIVE_RECORD_RELATION_MODULE_NAMES = [
+ "GeneratedRelationMethods",
+ "GeneratedAssociationRelationMethods",
+ ].freeze
+
+ ConstantType = type_member { { fixed: T.all(Module, ::StateMachines::ClassMethods) } }
+
+ sig { override.void }
+ def decorate
+ return if constant.state_machines.empty?
+
+ root.create_path(T.unsafe(constant)) do |klass|
+ instance_module_name = "StateMachineInstanceHelperModule"
+ class_module_name = "StateMachineClassHelperModule"
+
+ instance_module = RBI::Module.new(instance_module_name)
+ klass << instance_module
+
+ class_module = RBI::Module.new(class_module_name)
+ klass << class_module
+
+ constant.state_machines.each_value do |machine|
+ state_type = state_type_for(machine)
+
+ define_state_accessor(instance_module, machine, state_type)
+ define_state_predicate(instance_module, machine)
+ define_event_helpers(instance_module, machine)
+ define_path_helpers(instance_module, machine)
+ define_name_helpers(instance_module, class_module, machine)
+ define_scopes(class_module, machine)
+
+ define_state_methods(instance_module, machine)
+ define_event_methods(instance_module, machine)
+ end
+
+ if uses_active_record_integration?(constant)
+ define_activerecord_methods(instance_module)
+
+ [
+ Tapioca::Dsl::Helpers::ActiveRecordConstantsHelper::RelationMethodsModuleName,
+ Tapioca::Dsl::Helpers::ActiveRecordConstantsHelper::AssociationRelationMethodsModuleName,
+ ].each do |module_name|
+ klass.create_module(module_name).create_include(class_module_name)
+ end
+ end
+
+ klass.create_include(instance_module_name)
+ klass.create_extend(class_module_name)
+ end
+ end
+
+ class << self
+ extend T::Sig
+
+ sig { override.returns(T::Enumerable[Module]) }
+ def gather_constants
+ all_classes.select { |mod| ::StateMachines::InstanceMethods > mod }
+ end
+ end
+
+ private
+
+ sig { params(constant: Module).returns(T::Boolean) }
+ def uses_active_record_integration?(constant)
+ ::StateMachines::Integrations.match(constant)&.integration_name == :active_record
+ end
+
+ sig { params(machine: ::StateMachines::Machine).returns(String) }
+ def state_type_for(machine)
+ value_types = machine.states.map { |state| state.value.class.name }.uniq
+
+ if value_types.size == 1
+ value_types.first
+ else
+ "T.any(#{value_types.join(", ")})"
+ end
+ end
+
+ sig { params(instance_module: RBI::Module).void }
+ def define_activerecord_methods(instance_module)
+ instance_module.create_method(
+ "changed_for_autosave?",
+ return_type: "T::Boolean",
+ )
+ end
+
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_state_methods(instance_module, machine)
+ machine.states.each do |state|
+ instance_module.create_method(
+ "#{state.qualified_name}?",
+ return_type: "T::Boolean",
+ )
+ end
+ end
+
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_event_methods(instance_module, machine)
+ machine.events.each do |event|
+ instance_module.create_method(
+ "can_#{event.qualified_name}?",
+ return_type: "T::Boolean",
+ )
+ instance_module.create_method(
+ "#{event.qualified_name}_transition",
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T.nilable(::StateMachines::Transition)",
+ )
+ instance_module.create_method(
+ event.qualified_name.to_s,
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T::Boolean",
+ )
+ instance_module.create_method(
+ "#{event.qualified_name}!",
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T::Boolean",
+ )
+ end
+ end
+
+ sig do
+ params(
+ instance_module: RBI::Module,
+ machine: ::StateMachines::Machine,
+ state_type: String,
+ ).void
+ end
+ def define_state_accessor(instance_module, machine, state_type)
+ owner_class = machine.owner_class
+ attribute = machine.attribute.to_sym
+ attribute_name = machine.attribute.to_s
+
+ # AR classes don't define their attributes until the DB is hit and they're fully loaded, so force it here if
+ # needed
+ if !owner_class.instance_methods.include?(attribute) && owner_class.respond_to?(:define_attribute_methods)
+ owner_class.define_attribute_methods
+ end
+
+ if owner_class.instance_methods.include?(attribute)
+ instance_module.create_method(
+ attribute_name,
+ return_type: state_type,
+ ) if ::StateMachines::HelperModule === owner_class.instance_method(attribute).owner
+ instance_module.create_method(
+ "#{attribute_name}=",
+ parameters: [create_param("value", type: state_type)],
+ return_type: state_type,
+ ) if ::StateMachines::HelperModule === owner_class.instance_method("#{attribute}=").owner
+ end
+ end
+
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_state_predicate(instance_module, machine)
+ instance_module.create_method(
+ "#{machine.name}?",
+ parameters: [create_param("state", type: "T.any(String, Symbol)")],
+ return_type: "T::Boolean",
+ )
+ end
+
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_event_helpers(instance_module, machine)
+ events_attribute = machine.attribute(:events).to_s
+ transitions_attribute = machine.attribute(:transitions).to_s
+ event_attribute = machine.attribute(:event).to_s
+ event_transition_attribute = machine.attribute(:event_transition).to_s
+
+ instance_module.create_method(
+ events_attribute,
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T::Array[T.any(String, Symbol)]",
+ )
+ instance_module.create_method(
+ transitions_attribute,
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T::Array[::StateMachines::Transition]",
+ )
+ instance_module.create_method(
+ "fire_#{event_attribute}",
+ parameters: [
+ create_param("event", type: "T.any(String, Symbol)"),
+ create_rest_param("args", type: "T.untyped"),
+ ],
+ return_type: "T::Boolean",
+ )
+ if machine.action
+ instance_module.create_method(
+ event_attribute,
+ return_type: "T.nilable(Symbol)",
+ )
+ instance_module.create_method(
+ "#{event_attribute}=",
+ parameters: [create_param("value", type: "T.any(String, Symbol)")],
+ return_type: "T.any(String, Symbol)",
+ )
+ instance_module.create_method(
+ event_transition_attribute,
+ return_type: "T.nilable(::StateMachines::Transition)",
+ )
+ instance_module.create_method(
+ "#{event_transition_attribute}=",
+ parameters: [create_param("value", type: "::StateMachines::Transition")],
+ return_type: "::StateMachines::Transition",
+ )
+ end
+ end
+
+ sig { params(instance_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_path_helpers(instance_module, machine)
+ paths_attribute = machine.attribute(:paths).to_s
+
+ instance_module.create_method(
+ paths_attribute,
+ parameters: [create_rest_param("args", type: "T.untyped")],
+ return_type: "T::Array[::StateMachines::Transition]",
+ )
+ end
+
+ sig do
+ params(
+ instance_module: RBI::Module,
+ class_module: RBI::Module,
+ machine: ::StateMachines::Machine,
+ ).void
+ end
+ def define_name_helpers(instance_module, class_module, machine)
+ name_attribute = machine.attribute(:name).to_s
+ event_name_attribute = machine.attribute(:event_name).to_s
+
+ class_module.create_method(
+ "human_#{name_attribute}",
+ parameters: [create_param("state", type: "T.any(String, Symbol)")],
+ return_type: "String",
+ )
+ class_module.create_method(
+ "human_#{event_name_attribute}",
+ parameters: [create_param("event", type: "T.any(String, Symbol)")],
+ return_type: "String",
+ )
+ instance_module.create_method(
+ name_attribute,
+ return_type: "T.any(String, Symbol)",
+ )
+ instance_module.create_method(
+ "human_#{name_attribute}",
+ return_type: "String",
+ )
+ end
+
+ sig { params(class_module: RBI::Module, machine: ::StateMachines::Machine).void }
+ def define_scopes(class_module, machine)
+ helper_modules = machine.instance_variable_get(:@helper_modules)
+ class_methods = helper_modules[:class].instance_methods(false)
+
+ class_methods
+ .select { |method| method.to_s.start_with?("with_", "without_") }
+ .each do |method|
+ class_module.create_method(
+ method.to_s,
+ parameters: [create_rest_param("states", type: "T.any(String, Symbol)")],
+ return_type: "T.untyped",
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/tapioca/dsl/compilers/state_machines_extended.rb b/lib/tapioca/dsl/compilers/state_machines_extended.rb
deleted file mode 100644
index aee0aa1..0000000
--- a/lib/tapioca/dsl/compilers/state_machines_extended.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# typed: ignore
-# frozen_string_literal: true
-
-require "tapioca/dsl/compilers/state_machines"
-
-return unless defined?(Tapioca::Dsl::Compilers::StateMachines)
-
-module Tapioca
- module Dsl
- module Compilers
- # `Tapioca::Dsl::Compilers::StateMachinesExtended` extends the default state machines compiler provided by Tapioca
- # to allow for calling `with_state` and `without_state` on all Active Record relations. This is a temporary fix
- # until a more durable solution can be found for this type of issue.
- # See https://github.com/Shopify/tapioca/pull/1994#issuecomment-2302624697.
- class StateMachinesExtended < ::Tapioca::Dsl::Compilers::StateMachines
- ACTIVE_RECORD_RELATION_MODULE_NAMES = [
- "GeneratedRelationMethods",
- "GeneratedAssociationRelationMethods",
- ].freeze
-
- def decorate
- # This should really get checked at the gather_constants level but here we are...
- return if T::AbstractUtils.abstract_module?(constant)
- return if constant.state_machines.empty?
-
- # This is a hack to make sure the instance methods are defined on the constant. Somehow the constant is being
- # loaded but the actual `state_machine` call is not being executed, so the instance methods don't exist yet.
- # Instantiating an empty class fixes it.
- constant.try(:new)
-
- super()
-
- root.create_path(T.unsafe(constant)) do |klass|
- class_module_name = "StateMachineClassHelperModule"
-
- ACTIVE_RECORD_RELATION_MODULE_NAMES.each do |module_name|
- klass.create_module(module_name).create_include(class_module_name)
- end
- end
- end
- end
- end
- end
-end
diff --git a/manual/compilers.md b/manual/compilers.md
index bfa8810..e9e0fa4 100644
--- a/manual/compilers.md
+++ b/manual/compilers.md
@@ -10,5 +10,4 @@ This list is an evergeen list of currently available compilers.
* [AttrJson](compiler_attrjson.md)
* [MoneyRails](compiler_moneyrails.md)
* [Paperclip](compiler_paperclip.md)
-* [StateMachinesExtended](compiler_statemachinesextended.md)
diff --git a/sorbet/rbi/gems/state_machines@0.6.0.rbi b/sorbet/rbi/gems/state_machines@0.6.0.rbi
new file mode 100644
index 0000000..899c057
--- /dev/null
+++ b/sorbet/rbi/gems/state_machines@0.6.0.rbi
@@ -0,0 +1,5759 @@
+# typed: true
+
+# DO NOT EDIT MANUALLY
+# This is an autogenerated file for types exported from the `state_machines` gem.
+# Please instead update this file by running `bin/tapioca gem state_machines`.
+
+
+class Class < ::Module
+ include ::StateMachines::MacroMethods
+end
+
+# source://state_machines//lib/state_machines/assertions.rb#1
+class Hash
+ include ::Enumerable
+
+ # Validates that the given hash only includes at *most* one of a set of
+ # exclusive keys. If more than one key is found, an ArgumentError will be
+ # raised.
+ #
+ # == Examples
+ #
+ # options = {:only => :on, :except => :off}
+ # options.assert_exclusive_keys(:only) # => nil
+ # options.assert_exclusive_keys(:except) # => nil
+ # options.assert_exclusive_keys(:only, :except) # => ArgumentError: Conflicting keys: only, except
+ # options.assert_exclusive_keys(:only, :except, :with) # => ArgumentError: Conflicting keys: only, except
+ #
+ # @raise [ArgumentError]
+ #
+ # source://state_machines//lib/state_machines/assertions.rb#35
+ def assert_exclusive_keys(*exclusive_keys); end
+
+ # Validate all keys in a hash match *valid_keys, raising ArgumentError
+ # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
+ # use strings for keys but assert symbols as keys, this will fail.
+ #
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
+ # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
+ # Code from ActiveSupport
+ #
+ # source://state_machines//lib/state_machines/assertions.rb#14
+ def assert_valid_keys(*valid_keys); end
+end
+
+# A state machine is a model of behavior composed of states, events, and
+# transitions. This helper adds support for defining this type of
+# functionality on any Ruby class.
+#
+# source://state_machines//lib/state_machines/version.rb#1
+module StateMachines; end
+
+# Matches any given value. Since there is no configuration for this type of
+# matcher, it must be used as a singleton.
+#
+# source://state_machines//lib/state_machines/matcher.rb#23
+class StateMachines::AllMatcher < ::StateMachines::Matcher
+ include ::Singleton
+ extend ::Singleton::SingletonClassMethods
+
+ # Generates a blacklist matcher based on the given set of values
+ #
+ # == Examples
+ #
+ # matcher = StateMachines::AllMatcher.instance - [:parked, :idling]
+ # matcher.matches?(:parked) # => false
+ # matcher.matches?(:first_gear) # => true
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#33
+ def -(blacklist); end
+
+ # A human-readable description of this matcher. Always "all".
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#48
+ def description; end
+
+ # Always returns the given set of values
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#43
+ def filter(values); end
+
+ # Always returns true
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#38
+ def matches?(value, context = T.unsafe(nil)); end
+
+ class << self
+ private
+
+ def allocate; end
+ def new(*_arg0); end
+ end
+end
+
+# Represents a collection of transitions that were generated from attribute-
+# based events
+#
+# source://state_machines//lib/state_machines/transition_collection.rb#194
+class StateMachines::AttributeTransitionCollection < ::StateMachines::TransitionCollection
+ # @return [AttributeTransitionCollection] a new instance of AttributeTransitionCollection
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#195
+ def initialize(transitions = T.unsafe(nil), options = T.unsafe(nil)); end
+
+ private
+
+ # Tracks that before callbacks have now completed
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#231
+ def persist; end
+
+ # Resets callback tracking
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#237
+ def reset; end
+
+ # Resets the event attribute so it can be re-evaluated if attempted again
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#243
+ def rollback; end
+
+ # Hooks into running transition callbacks so that event / event transition
+ # attributes can be properly updated
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#203
+ def run_callbacks(index = T.unsafe(nil)); end
+end
+
+# Matches everything but a specific set of values
+#
+# source://state_machines//lib/state_machines/matcher.rb#74
+class StateMachines::BlacklistMatcher < ::StateMachines::Matcher
+ # A human-readable description of this matcher
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#94
+ def description; end
+
+ # Finds all values that are *not* within the blacklist configured for this
+ # matcher
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#89
+ def filter(values); end
+
+ # Checks whether the given value exists outside the blacklist configured
+ # for this matcher.
+ #
+ # == Examples
+ #
+ # matcher = StateMachines::BlacklistMatcher.new([:parked, :idling])
+ # matcher.matches?(:parked) # => false
+ # matcher.matches?(:first_gear) # => true
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#83
+ def matches?(value, context = T.unsafe(nil)); end
+end
+
+# 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.
+#
+# source://state_machines//lib/state_machines/branch.rb#6
+class StateMachines::Branch
+ include ::StateMachines::EvalHelpers
+
+ # Creates a new branch
+ #
+ # @return [Branch] a new instance of Branch
+ #
+ # source://state_machines//lib/state_machines/branch.rb#30
+ def initialize(options = T.unsafe(nil)); end
+
+ # source://state_machines//lib/state_machines/branch.rb#122
+ def draw(graph, event, valid_states); end
+
+ # The requirement for verifying the event being matched
+ #
+ # source://state_machines//lib/state_machines/branch.rb#17
+ def event_requirement; end
+
+ # The condition that must be met on an object
+ #
+ # source://state_machines//lib/state_machines/branch.rb#11
+ def if_condition; end
+
+ # 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+
+ #
+ # source://state_machines//lib/state_machines/branch.rb#27
+ def known_states; end
+
+ # 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.
+ #
+ # == Examples
+ #
+ # branch = StateMachines::Branch.new(:parked => :idling, :on => :ignite)
+ #
+ # branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
+ # branch.match(object, :on => :park) # => nil
+ #
+ # source://state_machines//lib/state_machines/branch.rb#114
+ def match(object, query = T.unsafe(nil)); end
+
+ # 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
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/branch.rb#85
+ def matches?(object, query = T.unsafe(nil)); end
+
+ # One or more requirements for verifying the states being matched. All
+ # requirements contain a mapping of {:from => matcher, :to => matcher}.
+ #
+ # source://state_machines//lib/state_machines/branch.rb#21
+ def state_requirements; end
+
+ # The condition that must *not* be met on an object
+ #
+ # source://state_machines//lib/state_machines/branch.rb#14
+ def unless_condition; end
+
+ protected
+
+ # Builds a matcher strategy to use for the given options. If neither a
+ # whitelist nor a blacklist option is specified, then an AllMatcher is
+ # built.
+ #
+ # source://state_machines//lib/state_machines/branch.rb#131
+ def build_matcher(options, whitelist_option, blacklist_option); end
+
+ # Verifies that the event requirement matches the given query
+ #
+ # source://state_machines//lib/state_machines/branch.rb#159
+ def match_event(query); end
+
+ # Verifies that all configured requirements (event and state) match the
+ # given query. If a match is found, then a hash containing the
+ # event/state requirements that passed will be returned; otherwise, nil.
+ #
+ # source://state_machines//lib/state_machines/branch.rb#150
+ def match_query(query); end
+
+ # Verifies that the state requirements match the given query. If a
+ # matching requirement is found, then it is returned.
+ #
+ # source://state_machines//lib/state_machines/branch.rb#165
+ def match_states(query); end
+
+ # Verifies that the conditionals for this branch evaluate to true for the
+ # given object
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/branch.rb#179
+ def matches_conditions?(object, query); end
+
+ # Verifies that an option in the given query matches the values required
+ # for that option
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/branch.rb#173
+ def matches_requirement?(query, option, requirement); end
+end
+
+# Callbacks represent hooks into objects that allow logic to be triggered
+# before, after, or around a specific set of transitions.
+#
+# source://state_machines//lib/state_machines/callback.rb#7
+class StateMachines::Callback
+ include ::StateMachines::EvalHelpers
+
+ # Creates a new callback that can get called based on the configured
+ # options.
+ #
+ # In addition to the possible configuration options for branches, 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
+ # default throw :halt technique).
+ #
+ # More information about how those options affect the behavior of the
+ # callback can be found in their attribute definitions.
+ #
+ # @raise [ArgumentError]
+ # @return [Callback] a new instance of Callback
+ #
+ # source://state_machines//lib/state_machines/callback.rb#123
+ def initialize(type, *args, &block); end
+
+ # The branch 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 branch to pass.
+ #
+ # See StateMachines::Branch for more information.
+ #
+ # source://state_machines//lib/state_machines/callback.rb#107
+ def branch; end
+
+ # Runs the callback as long as the transition context matches the branch
+ # requirements configured for this callback. If a block is provided, it
+ # will be called when the last method has run.
+ #
+ # If a terminator has been configured and it matches the result from the
+ # evaluated method, then the callback chain should be halted.
+ #
+ # source://state_machines//lib/state_machines/callback.rb#157
+ def call(object, context = T.unsafe(nil), *args, &block); end
+
+ # Gets a list of the states known to this callback by looking at the
+ # branch's known states
+ #
+ # source://state_machines//lib/state_machines/callback.rb#147
+ def known_states; end
+
+ # 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
+ #
+ # source://state_machines//lib/state_machines/callback.rb#100
+ def terminator; end
+
+ # The type of callback chain this callback is for. This can be one of the
+ # following:
+ # * +before+
+ # * +after+
+ # * +around+
+ # * +failure+
+ #
+ # source://state_machines//lib/state_machines/callback.rb#71
+ def type; end
+
+ # The type of callback chain this callback is for. This can be one of the
+ # following:
+ # * +before+
+ # * +after+
+ # * +around+
+ # * +failure+
+ #
+ # source://state_machines//lib/state_machines/callback.rb#71
+ def type=(_arg0); end
+
+ private
+
+ # Generates a method that can be bound to the object being transitioned
+ # when the callback is invoked
+ #
+ # source://state_machines//lib/state_machines/callback.rb#201
+ def bound_method(block); end
+
+ # Runs all of the methods configured for this callback.
+ #
+ # When running +around+ callbacks, this will evaluate each method and
+ # yield when the last method has yielded. The callback will only halt if
+ # one of the methods does not yield.
+ #
+ # For all other types of callbacks, this will evaluate each method in
+ # order. The callback will only halt if the resulting value from the
+ # method passes the terminator.
+ #
+ # source://state_machines//lib/state_machines/callback.rb#177
+ def run_methods(object, context = T.unsafe(nil), index = T.unsafe(nil), *args, &block); end
+
+ class << self
+ # 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:
+ #
+ # StateMachines::Callback.bind_to_object = true
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition do
+ # self.set_alarm
+ # end
+ # end
+ #
+ # def set_alarm
+ # ...
+ # end
+ # end
+ #
+ # source://state_machines//lib/state_machines/callback.rb#55
+ def bind_to_object; end
+
+ # 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:
+ #
+ # StateMachines::Callback.bind_to_object = true
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition do
+ # self.set_alarm
+ # end
+ # end
+ #
+ # def set_alarm
+ # ...
+ # end
+ # end
+ #
+ # source://state_machines//lib/state_machines/callback.rb#55
+ def bind_to_object=(_arg0); end
+
+ # 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 StateMachines::Callback#terminator for more information.
+ #
+ # source://state_machines//lib/state_machines/callback.rb#62
+ def terminator; end
+
+ # 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 StateMachines::Callback#terminator for more information.
+ #
+ # source://state_machines//lib/state_machines/callback.rb#62
+ def terminator=(_arg0); end
+ end
+end
+
+# source://state_machines//lib/state_machines/extensions.rb#2
+module StateMachines::ClassMethods
+ # Gets the current list of state machines defined for this class. This
+ # class-level attribute acts like an inheritable attribute. The attribute
+ # is available to each subclass, each having a copy of its superclass's
+ # attribute.
+ #
+ # The hash of state machines maps :attribute => +machine+, e.g.
+ #
+ # Vehicle.state_machines # => {:state => #}
+ #
+ # source://state_machines//lib/state_machines/extensions.rb#17
+ def state_machines; end
+
+ class << self
+ # source://state_machines//lib/state_machines/extensions.rb#3
+ def extended(base); end
+ end
+end
+
+# An error occurred during a state machine invocation
+#
+# source://state_machines//lib/state_machines/error.rb#3
+class StateMachines::Error < ::StandardError
+ # @return [Error] a new instance of Error
+ #
+ # source://state_machines//lib/state_machines/error.rb#7
+ def initialize(object, message = T.unsafe(nil)); end
+
+ # The object that failed
+ #
+ # source://state_machines//lib/state_machines/error.rb#5
+ def object; end
+end
+
+# Provides a set of helper methods for evaluating methods within the context
+# of an object.
+#
+# source://state_machines//lib/state_machines/eval_helpers.rb#4
+module StateMachines::EvalHelpers
+ # Evaluates one of several different types of methods within the context
+ # of the given object. Methods can be one of the following types:
+ # * Symbol
+ # * Method / Proc
+ # * String
+ #
+ # == Examples
+ #
+ # Below are examples of the various ways that a method can be evaluated
+ # on an object:
+ #
+ # class Person
+ # def initialize(name)
+ # @name = name
+ # end
+ #
+ # def name
+ # @name
+ # end
+ # end
+ #
+ # class PersonCallback
+ # def self.run(person)
+ # person.name
+ # end
+ # end
+ #
+ # person = Person.new('John Smith')
+ #
+ # evaluate_method(person, :name) # => "John Smith"
+ # evaluate_method(person, PersonCallback.method(:run)) # => "John Smith"
+ # evaluate_method(person, Proc.new {|person| person.name}) # => "John Smith"
+ # evaluate_method(person, lambda {|person| person.name}) # => "John Smith"
+ # evaluate_method(person, '@name') # => "John Smith"
+ #
+ # == Additional arguments
+ #
+ # Additional arguments can be passed to the methods being evaluated. If
+ # the method defines additional arguments other than the object context,
+ # then all arguments are required.
+ #
+ # For example,
+ #
+ # person = Person.new('John Smith')
+ #
+ # evaluate_method(person, lambda {|person| person.name}, 21) # => "John Smith"
+ # evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21) # => "John Smith is 21"
+ # evaluate_method(person, lambda {|person, age| "#{person.name} is #{age}"}, 21, 'male') # => ArgumentError: wrong number of arguments (3 for 2)
+ #
+ # source://state_machines//lib/state_machines/eval_helpers.rb#53
+ def evaluate_method(object, method, *args, &block); end
+end
+
+# An event defines an action that transitions an attribute from one state to
+# another. The state that an attribute is transitioned to depends on the
+# branches configured for the event.
+#
+# source://state_machines//lib/state_machines/event.rb#5
+class StateMachines::Event
+ include ::StateMachines::MatcherHelpers
+
+ # Creates a new event within the context of the given machine
+ #
+ # Configuration options:
+ # * :human_name - The human-readable version of this event's name
+ #
+ # @return [Event] a new instance of Event
+ #
+ # source://state_machines//lib/state_machines/event.rb#33
+ def initialize(machine, name, options = T.unsafe(nil)); end
+
+ # The list of branches that determine what state this event transitions
+ # objects to when fired
+ #
+ # source://state_machines//lib/state_machines/event.rb#23
+ def branches; end
+
+ # Determines whether any transitions can be performed for this event based
+ # on the current state of the given object.
+ #
+ # If the event can't be fired, then this will return false, otherwise true.
+ #
+ # *Note* that this will not take the object context into account. Although
+ # a transition may be possible based on the state machine definition,
+ # object-specific behaviors (like validations) may prevent it from firing.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/event.rb#107
+ def can_fire?(object, requirements = T.unsafe(nil)); end
+
+ # Evaluates the given block within the context of this event. This simply
+ # provides a DSL-like syntax for defining transitions.
+ #
+ # source://state_machines//lib/state_machines/event.rb#67
+ def context(&block); end
+
+ # source://state_machines//lib/state_machines/event.rb#183
+ def draw(graph, options = T.unsafe(nil)); end
+
+ # Attempts to perform the next available transition on the given object.
+ # If no transitions can be made, then this will return false, otherwise
+ # true.
+ #
+ # Any additional arguments are passed to the StateMachines::Transition#perform
+ # instance method.
+ #
+ # source://state_machines//lib/state_machines/event.rb#151
+ def fire(object, *args); end
+
+ # Transforms the event name into a more human-readable format, such as
+ # "turn on" instead of "turn_on"
+ #
+ # source://state_machines//lib/state_machines/event.rb#61
+ def human_name(klass = T.unsafe(nil)); end
+
+ # The human-readable name for the event
+ #
+ # source://state_machines//lib/state_machines/event.rb#19
+ def human_name=(_arg0); end
+
+ # Generates a nicely formatted description of this event's contents.
+ #
+ # For example,
+ #
+ # event = StateMachines::Event.new(machine, :park)
+ # event.transition all - :idling => :parked, :idling => same
+ # event # => # :parked, :idling => same]>
+ #
+ # source://state_machines//lib/state_machines/event.rb#194
+ def inspect; end
+
+ # A list of all of the states known to this event using the configured
+ # branches/transitions as the source
+ #
+ # source://state_machines//lib/state_machines/event.rb#27
+ def known_states; end
+
+ # The state machine for which this event is defined
+ #
+ # source://state_machines//lib/state_machines/event.rb#10
+ def machine; end
+
+ # The state machine for which this event is defined
+ #
+ # source://state_machines//lib/state_machines/event.rb#10
+ def machine=(_arg0); end
+
+ # The name of the event
+ #
+ # source://state_machines//lib/state_machines/event.rb#13
+ def name; end
+
+ # Marks the object as invalid and runs any failure callbacks associated with
+ # this event. This should get called anytime this event fails to transition.
+ #
+ # source://state_machines//lib/state_machines/event.rb#164
+ def on_failure(object, *args); end
+
+ # The fully-qualified name of the event, scoped by the machine's namespace
+ #
+ # source://state_machines//lib/state_machines/event.rb#16
+ def qualified_name; end
+
+ # Resets back to the initial state of the event, with no branches / known
+ # states associated. This allows you to redefine an event in situations
+ # where you either are re-using an existing state machine implementation
+ # or are subclassing machines.
+ #
+ # source://state_machines//lib/state_machines/event.rb#177
+ def reset; end
+
+ # Creates a new transition that determines what to change the current state
+ # to when this event fires.
+ #
+ # Since this transition is being defined within an event context, you do
+ # *not* need to specify the :on option for the transition. For
+ # example:
+ #
+ # state_machine do
+ # event :ignite do
+ # transition :parked => :idling, :idling => same, :if => :seatbelt_on? # Transitions to :idling if seatbelt is on
+ # transition all => :parked, :unless => :seatbelt_on? # Transitions to :parked if seatbelt is off
+ # end
+ # end
+ #
+ # See StateMachines::Machine#transition for a description of the possible
+ # configurations for defining transitions.
+ #
+ # @raise [ArgumentError]
+ #
+ # source://state_machines//lib/state_machines/event.rb#87
+ def transition(options); end
+
+ # Finds and builds the next transition that can be performed on the given
+ # object. If no transitions can be made, then this will return nil.
+ #
+ # Valid requirement options:
+ # * :from - One or more states being transitioned from. If none
+ # are specified, then this will be the object's current state.
+ # * :to - One or more states being transitioned to. If none are
+ # specified, then this will match any to state.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # source://state_machines//lib/state_machines/event.rb#121
+ def transition_for(object, requirements = T.unsafe(nil)); end
+
+ protected
+
+ # Add the various instance methods that can transition the object using
+ # the current event
+ #
+ # source://state_machines//lib/state_machines/event.rb#208
+ def add_actions; end
+
+ private
+
+ # Creates a copy of this event in addition to the list of associated
+ # branches to prevent conflicts across events within a class hierarchy.
+ #
+ # source://state_machines//lib/state_machines/event.rb#53
+ def initialize_copy(orig); end
+end
+
+# Represents a collection of events in a state machine
+#
+# source://state_machines//lib/state_machines/event_collection.rb#3
+class StateMachines::EventCollection < ::StateMachines::NodeCollection
+ # @return [EventCollection] a new instance of EventCollection
+ #
+ # source://state_machines//lib/state_machines/event_collection.rb#4
+ def initialize(machine); end
+
+ # Gets the transition that should be performed for the event stored in the
+ # given object's event attribute. This also takes an additional parameter
+ # for automatically invalidating the object if the event or transition are
+ # invalid. By default, this is turned off.
+ #
+ # *Note* that if a transition has already been generated for the event, then
+ # that transition will be used.
+ #
+ # == Examples
+ #
+ # class Vehicle < ActiveRecord::Base
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # events = Vehicle.state_machine.events
+ #
+ # vehicle.state_event = nil
+ # events.attribute_transition_for(vehicle) # => nil # Event isn't defined
+ #
+ # vehicle.state_event = 'invalid'
+ # events.attribute_transition_for(vehicle) # => false # Event is invalid
+ #
+ # vehicle.state_event = 'ignite'
+ # events.attribute_transition_for(vehicle) # => #
+ #
+ # source://state_machines//lib/state_machines/event_collection.rb#114
+ def attribute_transition_for(object, invalidate = T.unsafe(nil)); end
+
+ # Gets the list of transitions that can be run on the given object.
+ #
+ # Valid requirement options:
+ # * :from - One or more states being transitioned from. If none
+ # are specified, then this will be the object's current state.
+ # * :to - One or more states being transitioned to. If none are
+ # specified, then this will match any to state.
+ # * :on - One or more events that fire the transition. If none
+ # are specified, then this will match any event.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :park do
+ # transition :idling => :parked
+ # end
+ #
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # events = Vehicle.state_machine.events
+ #
+ # vehicle = Vehicle.new # => #
+ # events.transitions_for(vehicle) # => [#]
+ #
+ # vehicle.state = 'idling'
+ # events.transitions_for(vehicle) # => [#]
+ #
+ # # Search for explicit transitions regardless of the current state
+ # events.transitions_for(vehicle, :from => :parked) # => [#]
+ #
+ # source://state_machines//lib/state_machines/event_collection.rb#81
+ def transitions_for(object, requirements = T.unsafe(nil)); end
+
+ # Gets the list of events that can be fired on the given object.
+ #
+ # Valid requirement options:
+ # * :from - One or more states being transitioned from. If none
+ # are specified, then this will be the object's current state.
+ # * :to - One or more states being transitioned to. If none are
+ # specified, then this will match any to state.
+ # * :on - One or more events that fire the transition. If none
+ # are specified, then this will match any event.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :park do
+ # transition :idling => :parked
+ # end
+ #
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # events = Vehicle.state_machine(:state).events
+ #
+ # vehicle = Vehicle.new # => #
+ # events.valid_for(vehicle) # => [# :idling]>]
+ #
+ # vehicle.state = 'idling'
+ # events.valid_for(vehicle) # => [# :parked]>]
+ #
+ # source://state_machines//lib/state_machines/event_collection.rb#41
+ def valid_for(object, requirements = T.unsafe(nil)); end
+
+ private
+
+ # source://state_machines//lib/state_machines/event_collection.rb#136
+ def match(requirements); end
+end
+
+# Represents a type of module that defines instance / class methods for a
+# state machine
+#
+# source://state_machines//lib/state_machines/helper_module.rb#4
+class StateMachines::HelperModule < ::Module
+ # @return [HelperModule] a new instance of HelperModule
+ #
+ # source://state_machines//lib/state_machines/helper_module.rb#5
+ def initialize(machine, kind); end
+
+ # Provides a human-readable description of the module
+ #
+ # source://state_machines//lib/state_machines/helper_module.rb#11
+ def to_s; end
+end
+
+# source://state_machines//lib/state_machines/extensions.rb#22
+module StateMachines::InstanceMethods
+ # Runs one or more events in parallel. All events will run through the
+ # following steps:
+ # * Before callbacks
+ # * Persist state
+ # * Invoke action
+ # * After callbacks
+ #
+ # For example, if two events (for state machines A and B) are run in
+ # parallel, the order in which steps are run is:
+ # * A - Before transition callbacks
+ # * B - Before transition callbacks
+ # * A - Persist new state
+ # * B - Persist new state
+ # * A - Invoke action
+ # * B - Invoke action (only if different than A's action)
+ # * A - After transition callbacks
+ # * B - After transition callbacks
+ #
+ # *Note* that multiple events on the same state machine / attribute cannot
+ # be run in parallel. If this is attempted, an ArgumentError will be
+ # raised.
+ #
+ # == Halting callbacks
+ #
+ # When running multiple events in parallel, special consideration should
+ # be taken with regard to how halting within callbacks affects the flow.
+ #
+ # For *before* callbacks, any :halt error that's thrown will
+ # immediately cancel the perform for all transitions. As a result, it's
+ # possible for one event's transition to affect the continuation of
+ # another.
+ #
+ # On the other hand, any :halt error that's thrown within an
+ # *after* callback with only affect that event's transition. Other
+ # transitions will continue to run their own callbacks.
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # event :park do
+ # transition :idling => :parked
+ # end
+ # end
+ #
+ # state_machine :alarm_state, :namespace => 'alarm', :initial => :on do
+ # event :enable do
+ # transition all => :active
+ # end
+ #
+ # event :disable do
+ # transition all => :off
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ # vehicle.alarm_state # => "active"
+ #
+ # vehicle.fire_events(:ignite, :disable_alarm) # => true
+ # vehicle.state # => "idling"
+ # vehicle.alarm_state # => "off"
+ #
+ # # If any event fails, the entire event chain fails
+ # vehicle.fire_events(:ignite, :enable_alarm) # => false
+ # vehicle.state # => "idling"
+ # vehicle.alarm_state # => "off"
+ #
+ # # Exception raised on invalid event
+ # vehicle.fire_events(:park, :invalid) # => StateMachines::InvalidEvent: :invalid is an unknown event
+ # vehicle.state # => "idling"
+ # vehicle.alarm_state # => "off"
+ #
+ # source://state_machines//lib/state_machines/extensions.rb#100
+ def fire_events(*events); end
+
+ # Run one or more events in parallel. If any event fails to run, then
+ # a StateMachines::InvalidTransition exception will be raised.
+ #
+ # See StateMachines::InstanceMethods#fire_events for more information.
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # event :park do
+ # transition :idling => :parked
+ # end
+ # end
+ #
+ # state_machine :alarm_state, :namespace => 'alarm', :initial => :active do
+ # event :enable do
+ # transition all => :active
+ # end
+ #
+ # event :disable do
+ # transition all => :off
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.fire_events(:ignite, :disable_alarm) # => true
+ #
+ # vehicle.fire_events!(:ignite, :disable_alarm) # => StateMachines::InvalidParallelTransition: Cannot run events in parallel: ignite, disable_alarm
+ #
+ # source://state_machines//lib/state_machines/extensions.rb#137
+ def fire_events!(*events); end
+
+ protected
+
+ # source://state_machines//lib/state_machines/extensions.rb#144
+ def initialize_state_machines(options = T.unsafe(nil), &block); end
+end
+
+# An invalid integration was registered
+#
+# source://state_machines//lib/state_machines/error.rb#42
+class StateMachines::IntegrationError < ::StandardError; end
+
+# An invalid integration was specified
+#
+# source://state_machines//lib/state_machines/error.rb#15
+class StateMachines::IntegrationNotFound < ::StateMachines::Error
+ # @return [IntegrationNotFound] a new instance of IntegrationNotFound
+ #
+ # source://state_machines//lib/state_machines/error.rb#16
+ def initialize(name); end
+
+ # source://state_machines//lib/state_machines/error.rb#32
+ def error_message; end
+
+ # source://state_machines//lib/state_machines/error.rb#28
+ def no_integrations; end
+
+ # source://state_machines//lib/state_machines/error.rb#20
+ def valid_integrations; end
+
+ # source://state_machines//lib/state_machines/error.rb#24
+ def valid_integrations_name; end
+end
+
+# Integrations allow state machines to take advantage of features within the
+# context of a particular library. This is currently most useful with
+# database libraries. For example, the various database integrations allow
+# state machines to hook into features like:
+# * Saving
+# * Transactions
+# * Observers
+# * Scopes
+# * Callbacks
+# * Validation errors
+#
+# This type of integration allows the user to work with state machines in a
+# fashion similar to other object models in their application.
+#
+# The integration interface is loosely defined by various unimplemented
+# methods in the StateMachines::Machine class. See that class or the various
+# built-in integrations for more information about how to define additional
+# integrations.
+#
+# source://state_machines//lib/state_machines/integrations.rb#20
+module StateMachines::Integrations
+ class << self
+ # Finds an integration with the given name. If the integration cannot be
+ # found, then a NameError exception will be raised.
+ #
+ # == Examples
+ #
+ # StateMachines::Integrations.find_by_name(:active_model) # => StateMachines::Integrations::ActiveModel
+ # StateMachines::Integrations.find_by_name(:active_record) # => StateMachines::Integrations::ActiveRecord
+ # StateMachines::Integrations.find_by_name(:invalid) # => StateMachines::IntegrationNotFound: :invalid is an invalid integration
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#99
+ def find_by_name(name); end
+
+ # Gets a list of all of the available integrations for use.
+ #
+ # == Example
+ #
+ # StateMachines::Integrations.integrations
+ # # => []
+ # StateMachines::Integrations.register(StateMachines::Integrations::ActiveModel)
+ # StateMachines::Integrations.integrations
+ # # => [StateMachines::Integrations::ActiveModel]
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#48
+ def integrations; end
+
+ # Gets a list of all of the available integrations for use.
+ #
+ # == Example
+ #
+ # StateMachines::Integrations.integrations
+ # # => []
+ # StateMachines::Integrations.register(StateMachines::Integrations::ActiveModel)
+ # StateMachines::Integrations.integrations
+ # # => [StateMachines::Integrations::ActiveModel]
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#48
+ def list; end
+
+ # Attempts to find an integration that matches the given class. This will
+ # look through all of the built-in integrations under the StateMachines::Integrations
+ # namespace and find one that successfully matches the class.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # end
+ #
+ # class ActiveModelVehicle
+ # include ActiveModel::Observing
+ # include ActiveModel::Validations
+ # end
+ #
+ # class ActiveRecordVehicle < ActiveRecord::Base
+ # end
+ #
+ # StateMachines::Integrations.match(Vehicle) # => nil
+ # StateMachines::Integrations.match(ActiveModelVehicle) # => StateMachines::Integrations::ActiveModel
+ # StateMachines::Integrations.match(ActiveRecordVehicle) # => StateMachines::Integrations::ActiveRecord
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#75
+ def match(klass); end
+
+ # Attempts to find an integration that matches the given list of ancestors.
+ # This will look through all of the built-in integrations under the StateMachines::Integrations
+ # namespace and find one that successfully matches one of the ancestors.
+ #
+ # == Examples
+ #
+ # StateMachines::Integrations.match_ancestors([]) # => nil
+ # StateMachines::Integrations.match_ancestors([ActiveRecord::Base]) # => StateMachines::Integrations::ActiveModel
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#87
+ def match_ancestors(ancestors); end
+
+ # Register integration
+ #
+ # source://state_machines//lib/state_machines/integrations.rb#25
+ def register(name_or_module); end
+
+ # source://state_machines//lib/state_machines/integrations.rb#35
+ def reset; end
+
+ private
+
+ # source://state_machines//lib/state_machines/integrations.rb#105
+ def add(integration); end
+ end
+end
+
+# Provides a set of base helpers for managing individual integrations
+#
+# source://state_machines//lib/state_machines/integrations/base.rb#4
+module StateMachines::Integrations::Base
+ mixes_in_class_methods ::StateMachines::Integrations::Base::ClassMethods
+
+ class << self
+ # source://state_machines//lib/state_machines/integrations/base.rb#36
+ def included(base); end
+ end
+end
+
+# source://state_machines//lib/state_machines/integrations/base.rb#5
+module StateMachines::Integrations::Base::ClassMethods
+ # The default options to use for state machines using this integration
+ #
+ # source://state_machines//lib/state_machines/integrations/base.rb#7
+ def defaults; end
+
+ # The name of the integration
+ #
+ # source://state_machines//lib/state_machines/integrations/base.rb#10
+ def integration_name; end
+
+ # Whether the integration should be used for the given class.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/integrations/base.rb#26
+ def matches?(klass); end
+
+ # Whether the integration should be used for the given list of ancestors.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/integrations/base.rb#31
+ def matches_ancestors?(ancestors); end
+
+ # The list of ancestor names that cause this integration to matched.
+ #
+ # source://state_machines//lib/state_machines/integrations/base.rb#21
+ def matching_ancestors; end
+end
+
+# A method was called in an invalid state context
+#
+# source://state_machines//lib/state_machines/error.rb#110
+class StateMachines::InvalidContext < ::StateMachines::Error; end
+
+# An invalid event was specified
+#
+# source://state_machines//lib/state_machines/error.rb#46
+class StateMachines::InvalidEvent < ::StateMachines::Error
+ # @return [InvalidEvent] a new instance of InvalidEvent
+ #
+ # source://state_machines//lib/state_machines/error.rb#50
+ def initialize(object, event_name); end
+
+ # The event that was attempted to be run
+ #
+ # source://state_machines//lib/state_machines/error.rb#48
+ def event; end
+end
+
+# A set of transition failed to run in parallel
+#
+# source://state_machines//lib/state_machines/error.rb#98
+class StateMachines::InvalidParallelTransition < ::StateMachines::Error
+ # @return [InvalidParallelTransition] a new instance of InvalidParallelTransition
+ #
+ # source://state_machines//lib/state_machines/error.rb#102
+ def initialize(object, events); end
+
+ # The set of events that failed the transition(s)
+ #
+ # source://state_machines//lib/state_machines/error.rb#100
+ def events; end
+end
+
+# An invalid transition was attempted
+#
+# source://state_machines//lib/state_machines/error.rb#57
+class StateMachines::InvalidTransition < ::StateMachines::Error
+ # @return [InvalidTransition] a new instance of InvalidTransition
+ #
+ # source://state_machines//lib/state_machines/error.rb#64
+ def initialize(object, machine, event); end
+
+ # The event that triggered the failed transition
+ #
+ # source://state_machines//lib/state_machines/error.rb#77
+ def event; end
+
+ # The current state value for the machine
+ #
+ # source://state_machines//lib/state_machines/error.rb#62
+ def from; end
+
+ # The name for the current state
+ #
+ # source://state_machines//lib/state_machines/error.rb#87
+ def from_name; end
+
+ # The machine attempting to be transitioned
+ #
+ # source://state_machines//lib/state_machines/error.rb#59
+ def machine; end
+
+ # The fully-qualified name of the event that triggered the failed transition
+ #
+ # source://state_machines//lib/state_machines/error.rb#82
+ def qualified_event; end
+
+ # The fully-qualified name for the current state
+ #
+ # source://state_machines//lib/state_machines/error.rb#92
+ def qualified_from_name; end
+end
+
+# Matches a loopback of two values within a context. Since there is no
+# configuration for this type of matcher, it must be used as a singleton.
+#
+# source://state_machines//lib/state_machines/matcher.rb#101
+class StateMachines::LoopbackMatcher < ::StateMachines::Matcher
+ include ::Singleton
+ extend ::Singleton::SingletonClassMethods
+
+ # A human-readable description of this matcher. Always "same".
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#117
+ def description; end
+
+ # Checks whether the given value matches what the value originally was.
+ # This value should be defined in the context.
+ #
+ # == Examples
+ #
+ # matcher = StateMachines::LoopbackMatcher.instance
+ # matcher.matches?(:parked, :from => :parked) # => true
+ # matcher.matches?(:parked, :from => :idling) # => false
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#112
+ def matches?(value, context); end
+
+ class << self
+ private
+
+ def allocate; end
+ def new(*_arg0); end
+ end
+end
+
+# Represents a state machine for a particular attribute. State machines
+# consist of states, events and a set of transitions that define how the
+# state changes after a particular event is fired.
+#
+# A state machine will not know all of the possible states for an object
+# unless they are referenced *somewhere* in the state machine definition.
+# As a result, any unused states should be defined with the +other_states+
+# or +state+ helper.
+#
+# == Actions
+#
+# When an action is configured for a state machine, it is invoked when an
+# object transitions via an event. The success of the event becomes
+# dependent on the success of the action. If the action is successful, then
+# the transitioned state remains persisted. However, if the action fails
+# (by returning false), the transitioned state will be rolled back.
+#
+# For example,
+#
+# class Vehicle
+# attr_accessor :fail, :saving_state
+#
+# state_machine :initial => :parked, :action => :save do
+# event :ignite do
+# transition :parked => :idling
+# end
+#
+# event :park do
+# transition :idling => :parked
+# end
+# end
+#
+# def save
+# @saving_state = state
+# fail != true
+# end
+# end
+#
+# vehicle = Vehicle.new # => #
+# vehicle.save # => true
+# vehicle.saving_state # => "parked" # The state was "parked" was save was called
+#
+# # Successful event
+# vehicle.ignite # => true
+# vehicle.saving_state # => "idling" # The state was "idling" when save was called
+# vehicle.state # => "idling"
+#
+# # Failed event
+# vehicle.fail = true
+# vehicle.park # => false
+# vehicle.saving_state # => "parked"
+# vehicle.state # => "idling"
+#
+# As shown, even though the state is set prior to calling the +save+ action
+# on the object, it will be rolled back to the original state if the action
+# fails. *Note* that this will also be the case if an exception is raised
+# while calling the action.
+#
+# === Indirect transitions
+#
+# In addition to the action being run as the _result_ of an event, the action
+# can also be used to run events itself. For example, using the above as an
+# example:
+#
+# vehicle = Vehicle.new # => #
+#
+# vehicle.state_event = 'ignite'
+# vehicle.save # => true
+# vehicle.state # => "idling"
+# vehicle.state_event # => nil
+#
+# As can be seen, the +save+ action automatically invokes the event stored in
+# the +state_event+ attribute (:ignite in this case).
+#
+# One important note about using this technique for running transitions is
+# that if the class in which the state machine is defined *also* defines the
+# action being invoked (and not a superclass), then it must manually run the
+# StateMachine hook that checks for event attributes.
+#
+# For example, in ActiveRecord, DataMapper, Mongoid, MongoMapper, and Sequel,
+# the default action (+save+) is already defined in a base class. As a result,
+# when a state machine is defined in a model / resource, StateMachine can
+# automatically hook into the +save+ action.
+#
+# On the other hand, the Vehicle class from above defined its own +save+
+# method (and there is no +save+ method in its superclass). As a result, it
+# must be modified like so:
+#
+# def save
+# self.class.state_machines.transitions(self, :save).perform do
+# @saving_state = state
+# fail != true
+# end
+# end
+#
+# This will add in the functionality for firing the event stored in the
+# +state_event+ attribute.
+#
+# == Callbacks
+#
+# Callbacks are supported for hooking before and after every possible
+# transition in the machine. Each callback is invoked in the order in which
+# it was defined. See StateMachines::Machine#before_transition and
+# StateMachines::Machine#after_transition for documentation on how to define
+# new callbacks.
+#
+# *Note* that callbacks only get executed within the context of an event. As
+# a result, if a class has an initial state when it's created, any callbacks
+# that would normally get executed when the object enters that state will
+# *not* get triggered.
+#
+# For example,
+#
+# class Vehicle
+# state_machine initial: :parked do
+# after_transition all => :parked do
+# raise ArgumentError
+# end
+# ...
+# end
+# end
+#
+# vehicle = Vehicle.new # => #
+# vehicle.save # => true (no exception raised)
+#
+# If you need callbacks to get triggered when an object is created, this
+# should be done by one of the following techniques:
+# * Use a before :create or equivalent hook:
+#
+# class Vehicle
+# before :create, :track_initial_transition
+#
+# state_machine do
+# ...
+# end
+# end
+#
+# * Set an initial state and use the correct event to create the
+# object with the proper state, resulting in callbacks being triggered and
+# the object getting persisted (note that the :pending state is
+# actually stored as nil):
+#
+# class Vehicle
+# state_machine initial: :pending
+# after_transition pending: :parked, do: :track_initial_transition
+#
+# event :park do
+# transition pending: :parked
+# end
+#
+# state :pending, value: nil
+# end
+# end
+#
+# vehicle = Vehicle.new
+# vehicle.park
+#
+# * Use a default event attribute that will automatically trigger when the
+# configured action gets run (note that the :pending state is
+# actually stored as nil):
+#
+# class Vehicle < ActiveRecord::Base
+# state_machine initial: :pending
+# after_transition pending: :parked, do: :track_initial_transition
+#
+# event :park do
+# transition pending: :parked
+# end
+#
+# state :pending, value: nil
+# end
+#
+# def initialize(*)
+# super
+# self.state_event = 'park'
+# end
+# end
+#
+# vehicle = Vehicle.new
+# vehicle.save
+#
+# === Canceling callbacks
+#
+# Callbacks can be canceled by throwing :halt at any point during the
+# callback. For example,
+#
+# ...
+# throw :halt
+# ...
+#
+# If a +before+ callback halts the chain, the associated transition and all
+# later callbacks are canceled. If an +after+ callback halts the chain,
+# the later callbacks are canceled, but the transition is still successful.
+#
+# These same rules apply to +around+ callbacks with the exception that any
+# +around+ callback that doesn't yield will essentially result in :halt being
+# thrown. Any code executed after the yield will behave in the same way as
+# +after+ callbacks.
+#
+# *Note* that if a +before+ callback fails and the bang version of an event
+# was invoked, an exception will be raised instead of returning false. For
+# example,
+#
+# class Vehicle
+# state_machine :initial => :parked do
+# before_transition any => :idling, :do => lambda {|vehicle| throw :halt}
+# ...
+# end
+# end
+#
+# vehicle = Vehicle.new
+# vehicle.park # => false
+# vehicle.park! # => StateMachines::InvalidTransition: Cannot transition state via :park from "idling"
+#
+# == Observers
+#
+# Observers, in the sense of external classes and *not* Ruby's Observable
+# mechanism, can hook into state machines as well. Such observers use the
+# same callback api that's used internally.
+#
+# Below are examples of defining observers for the following state machine:
+#
+# class Vehicle
+# state_machine do
+# event :park do
+# transition idling: :parked
+# end
+# ...
+# end
+# ...
+# end
+#
+# Event/Transition behaviors:
+#
+# class VehicleObserver
+# def self.before_park(vehicle, transition)
+# logger.info "#{vehicle} instructed to park... state is: #{transition.from}, state will be: #{transition.to}"
+# end
+#
+# def self.after_park(vehicle, transition, result)
+# logger.info "#{vehicle} instructed to park... state was: #{transition.from}, state is: #{transition.to}"
+# end
+#
+# def self.before_transition(vehicle, transition)
+# logger.info "#{vehicle} instructed to #{transition.event}... #{transition.attribute} is: #{transition.from}, #{transition.attribute} will be: #{transition.to}"
+# end
+#
+# def self.after_transition(vehicle, transition)
+# logger.info "#{vehicle} instructed to #{transition.event}... #{transition.attribute} was: #{transition.from}, #{transition.attribute} is: #{transition.to}"
+# end
+#
+# def self.around_transition(vehicle, transition)
+# logger.info Benchmark.measure { yield }
+# end
+# end
+#
+# Vehicle.state_machine do
+# before_transition :on => :park, :do => VehicleObserver.method(:before_park)
+# before_transition VehicleObserver.method(:before_transition)
+#
+# after_transition :on => :park, :do => VehicleObserver.method(:after_park)
+# after_transition VehicleObserver.method(:after_transition)
+#
+# around_transition VehicleObserver.method(:around_transition)
+# end
+#
+# One common callback is to record transitions for all models in the system
+# for auditing/debugging purposes. Below is an example of an observer that
+# can easily automate this process for all models:
+#
+# class StateMachineObserver
+# def self.before_transition(object, transition)
+# Audit.log_transition(object.attributes)
+# end
+# end
+#
+# [Vehicle, Switch, Project].each do |klass|
+# klass.state_machines.each do |attribute, machine|
+# machine.before_transition StateMachineObserver.method(:before_transition)
+# end
+# end
+#
+# Additional observer-like behavior may be exposed by the various integrations
+# available. See below for more information on integrations.
+#
+# == Overriding instance / class methods
+#
+# Hooking in behavior to the generated instance / class methods from the
+# state machine, events, and states is very simple because of the way these
+# methods are generated on the class. Using the class's ancestors, the
+# original generated method can be referred to via +super+. For example,
+#
+# class Vehicle
+# state_machine do
+# event :park do
+# ...
+# end
+# end
+#
+# def park(*args)
+# logger.info "..."
+# super
+# end
+# end
+#
+# In the above example, the +park+ instance method that's generated on the
+# Vehicle class (by the associated event) is overridden with custom behavior.
+# Once this behavior is complete, the original method from the state machine
+# is invoked by simply calling +super+.
+#
+# The same technique can be used for +state+, +state_name+, and all other
+# instance *and* class methods on the Vehicle class.
+#
+# == Method conflicts
+#
+# By default state_machine does not redefine methods that exist on
+# superclasses (*including* Object) or any modules (*including* Kernel) that
+# were included before it was defined. This is in order to ensure that
+# existing behavior on the class is not broken by the inclusion of
+# state_machine.
+#
+# If a conflicting method is detected, state_machine will generate a warning.
+# For example, consider the following class:
+#
+# class Vehicle
+# state_machine do
+# event :open do
+# ...
+# end
+# end
+# end
+#
+# In the above class, an event named "open" is defined for its state machine.
+# However, "open" is already defined as an instance method in Ruby's Kernel
+# module that gets included in every Object. As a result, state_machine will
+# generate the following warning:
+#
+# Instance method "open" is already defined in Object, use generic helper instead or set StateMachines::Machine.ignore_method_conflicts = true.
+#
+# Even though you may not be using Kernel's implementation of the "open"
+# instance method, state_machine isn't aware of this and, as a result, stays
+# safe and just skips redefining the method.
+#
+# As with almost all helpers methods defined by state_machine in your class,
+# there are generic methods available for working around this method conflict.
+# In the example above, you can invoke the "open" event like so:
+#
+# vehicle = Vehicle.new # => #
+# vehicle.fire_events(:open) # => true
+#
+# # This will not work
+# vehicle.open # => NoMethodError: private method `open' called for #
+#
+# If you want to take on the risk of overriding existing methods and just
+# ignore method conflicts altogether, you can do so by setting the following
+# configuration:
+#
+# StateMachines::Machine.ignore_method_conflicts = true
+#
+# This will allow you to define events like "open" as described above and
+# still generate the "open" instance helper method. For example:
+#
+# StateMachines::Machine.ignore_method_conflicts = true
+#
+# class Vehicle
+# state_machine do
+# event :open do
+# ...
+# end
+# end
+#
+# vehicle = Vehicle.new # => #
+# vehicle.open # => true
+#
+# By default, state_machine helps prevent you from making mistakes and
+# accidentally overriding methods that you didn't intend to. Once you
+# understand this and what the consequences are, setting the
+# +ignore_method_conflicts+ option is a perfectly reasonable workaround.
+#
+# == Integrations
+#
+# By default, state machines are library-agnostic, meaning that they work
+# on any Ruby class and have no external dependencies. However, there are
+# certain libraries which expose additional behavior that can be taken
+# advantage of by state machines.
+#
+# This library is built to work out of the box with a few popular Ruby
+# libraries that allow for additional behavior to provide a cleaner and
+# smoother experience. This is especially the case for objects backed by a
+# database that may allow for transactions, persistent storage,
+# search/filters, callbacks, etc.
+#
+# When a state machine is defined for classes using any of the above libraries,
+# it will try to automatically determine the integration to use (Agnostic,
+# ActiveModel, ActiveRecord, DataMapper, Mongoid, MongoMapper, or Sequel)
+# based on the class definition. To see how each integration affects the
+# machine's behavior, refer to all constants defined under the
+# StateMachines::Integrations namespace.
+#
+# source://state_machines//lib/state_machines/machine.rb#400
+class StateMachines::Machine
+ include ::StateMachines::EvalHelpers
+ include ::StateMachines::MatcherHelpers
+
+ # Creates a new state machine for the given attribute
+ #
+ # @return [Machine] a new instance of Machine
+ #
+ # source://state_machines//lib/state_machines/machine.rb#503
+ def initialize(owner_class, *args, &block); end
+
+ # The action to invoke when an object transitions
+ #
+ # source://state_machines//lib/state_machines/machine.rb#492
+ def action; end
+
+ # Determines whether an action hook was defined for firing attribute-based
+ # event transitions when the configured action gets called.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1883
+ def action_hook?(self_only = T.unsafe(nil)); end
+
+ # Creates a callback that will be invoked *after* a transition failures to
+ # be performed so long as the given requirements match the transition.
+ #
+ # See +before_transition+ for a description of the possible configurations
+ # for defining callbacks. *Note* however that you cannot define the state
+ # requirements in these callbacks. You may only define event requirements.
+ #
+ # = The callback
+ #
+ # Failure callbacks get invoked whenever an event fails to execute. This
+ # can happen when no transition is available, a +before+ callback halts
+ # execution, or the action associated with this machine fails to succeed.
+ # In any of these cases, any failure callback that matches the attempted
+ # transition will be run.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine do
+ # after_failure do |vehicle, transition|
+ # logger.error "vehicle #{vehicle} failed to transition on #{transition.event}"
+ # end
+ #
+ # after_failure :on => :ignite, :do => :log_ignition_failure
+ #
+ # ...
+ # end
+ # end
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1749
+ def after_failure(*args, &block); end
+
+ # Creates a callback that will be invoked *after* a transition is
+ # performed so long as the given requirements match the transition.
+ #
+ # See +before_transition+ for a description of the possible configurations
+ # for defining callbacks.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1654
+ def after_transition(*args, &block); end
+
+ # Creates a callback that will be invoked *around* a transition so long as
+ # the given requirements match the transition.
+ #
+ # == The callback
+ #
+ # Around callbacks wrap transitions, executing code both before and after.
+ # These callbacks are defined in the exact same manner as before / after
+ # callbacks with the exception that the transition must be yielded to in
+ # order to finish running it.
+ #
+ # If defining +around+ callbacks using blocks, you must yield within the
+ # transition by directly calling the block (since yielding is not allowed
+ # within blocks).
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine do
+ # around_transition do |block|
+ # Benchmark.measure { block.call }
+ # end
+ #
+ # around_transition do |vehicle, block|
+ # logger.info "vehicle was #{state}..."
+ # block.call
+ # logger.info "...and is now #{state}"
+ # end
+ #
+ # around_transition do |vehicle, transition, block|
+ # logger.info "before #{transition.event}: #{vehicle.state}"
+ # block.call
+ # logger.info "after #{transition.event}: #{vehicle.state}"
+ # end
+ # end
+ # end
+ #
+ # Notice that referencing the block is similar to doing so within an
+ # actual method definition in that it is always the last argument.
+ #
+ # On the other hand, if you're defining +around+ callbacks using method
+ # references, you can yield like normal:
+ #
+ # class Vehicle
+ # state_machine do
+ # around_transition :benchmark
+ # ...
+ # end
+ #
+ # def benchmark
+ # Benchmark.measure { yield }
+ # end
+ # end
+ #
+ # See +before_transition+ for a description of the possible configurations
+ # for defining callbacks.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1715
+ def around_transition(*args, &block); end
+
+ # Gets the actual name of the attribute on the machine's owner class that
+ # stores data with the given name.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#678
+ def attribute(name = T.unsafe(nil)); end
+
+ # Creates a callback that will be invoked *before* a transition is
+ # performed so long as the given requirements match the transition.
+ #
+ # == The callback
+ #
+ # Callbacks must be defined as either an argument, in the :do option, or
+ # as a block. For example,
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition :set_alarm
+ # before_transition :set_alarm, all => :parked
+ # before_transition all => :parked, :do => :set_alarm
+ # before_transition all => :parked do |vehicle, transition|
+ # vehicle.set_alarm
+ # end
+ # ...
+ # end
+ # end
+ #
+ # Notice that the first three callbacks are the same in terms of how the
+ # methods to invoke are defined. However, using the :do can
+ # provide for a more fluid DSL.
+ #
+ # In addition, multiple callbacks can be defined like so:
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition :set_alarm, :lock_doors, all => :parked
+ # before_transition all => :parked, :do => [:set_alarm, :lock_doors]
+ # before_transition :set_alarm do |vehicle, transition|
+ # vehicle.lock_doors
+ # end
+ # end
+ # end
+ #
+ # Notice that the different ways of configuring methods can be mixed.
+ #
+ # == State requirements
+ #
+ # Callbacks can require that the machine be transitioning from and to
+ # specific states. These requirements use a Hash syntax to map beginning
+ # states to ending states. For example,
+ #
+ # before_transition :parked => :idling, :idling => :first_gear, :do => :set_alarm
+ #
+ # In this case, the +set_alarm+ callback will only be called if the machine
+ # is transitioning from +parked+ to +idling+ or from +idling+ to +parked+.
+ #
+ # To help define state requirements, a set of helpers are available for
+ # slightly more complex matching:
+ # * all - Matches every state/event in the machine
+ # * all - [:parked, :idling, ...] - Matches every state/event except those specified
+ # * any - An alias for +all+ (matches every state/event in the machine)
+ # * same - Matches the same state being transitioned from
+ #
+ # See StateMachines::MatcherHelpers for more information.
+ #
+ # Examples:
+ #
+ # before_transition :parked => [:idling, :first_gear], :do => ... # Matches from parked to idling or first_gear
+ # before_transition all - [:parked, :idling] => :idling, :do => ... # Matches from every state except parked and idling to idling
+ # before_transition all => :parked, :do => ... # Matches all states to parked
+ # before_transition any => same, :do => ... # Matches every loopback
+ #
+ # == Event requirements
+ #
+ # In addition to state requirements, an event requirement can be defined so
+ # that the callback is only invoked on specific events using the +on+
+ # option. This can also use the same matcher helpers as the state
+ # requirements.
+ #
+ # Examples:
+ #
+ # before_transition :on => :ignite, :do => ... # Matches only on ignite
+ # before_transition :on => all - :ignite, :do => ... # Matches on every event except ignite
+ # before_transition :parked => :idling, :on => :ignite, :do => ... # Matches from parked to idling on ignite
+ #
+ # == Verbose Requirements
+ #
+ # Requirements can also be defined using verbose options rather than the
+ # implicit Hash syntax and helper methods described above.
+ #
+ # Configuration options:
+ # * :from - One or more states being transitioned from. If none
+ # are specified, then all states will match.
+ # * :to - One or more states being transitioned to. If none are
+ # specified, then all states will match.
+ # * :on - One or more events that fired the transition. If none
+ # are specified, then all events will match.
+ # * :except_from - One or more states *not* being transitioned from
+ # * :except_to - One more states *not* being transitioned to
+ # * :except_on - One or more events that *did not* fire the transition
+ #
+ # Examples:
+ #
+ # before_transition :from => :ignite, :to => :idling, :on => :park, :do => ...
+ # before_transition :except_from => :ignite, :except_to => :idling, :except_on => :park, :do => ...
+ #
+ # == Conditions
+ #
+ # In addition to the state/event requirements, a condition can also be
+ # defined to help determine whether the callback should be invoked.
+ #
+ # Configuration options:
+ # * :if - A method, proc or string to call to determine if the
+ # callback should occur (e.g. :if => :allow_callbacks, or
+ # :if => lambda {|user| user.signup_step > 2}). The method, proc or string
+ # should return or evaluate to a true or false value.
+ # * :unless - A method, proc or string to call to determine if the
+ # callback should not occur (e.g. :unless => :skip_callbacks, or
+ # :unless => lambda {|user| user.signup_step <= 2}). The method, proc or
+ # string should return or evaluate to a true or false value.
+ #
+ # Examples:
+ #
+ # before_transition :parked => :idling, :if => :moving?, :do => ...
+ # before_transition :on => :ignite, :unless => :seatbelt_on?, :do => ...
+ #
+ # == Accessing the transition
+ #
+ # In addition to passing the object being transitioned, the actual
+ # transition describing the context (e.g. event, from, to) can be accessed
+ # as well. This additional argument is only passed if the callback allows
+ # for it.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # # Only specifies one parameter (the object being transitioned)
+ # before_transition all => :parked do |vehicle|
+ # vehicle.set_alarm
+ # end
+ #
+ # # Specifies 2 parameters (object being transitioned and actual transition)
+ # before_transition all => :parked do |vehicle, transition|
+ # vehicle.set_alarm(transition)
+ # end
+ # end
+ #
+ # *Note* that the object in the callback will only be passed in as an
+ # argument if callbacks are configured to *not* be bound to the object
+ # involved. This is the default and may change on a per-integration basis.
+ #
+ # See StateMachines::Transition for more information about the
+ # attributes available on the transition.
+ #
+ # == Usage with delegates
+ #
+ # As noted above, state_machine uses the callback method's argument list
+ # arity to determine whether to include the transition in the method call.
+ # If you're using delegates, such as those defined in ActiveSupport or
+ # Forwardable, the actual arity of the delegated method gets masked. This
+ # means that callbacks which reference delegates will always get passed the
+ # transition as an argument. For example:
+ #
+ # class Vehicle
+ # extend Forwardable
+ # delegate :refresh => :dashboard
+ #
+ # state_machine do
+ # before_transition :refresh
+ # ...
+ # end
+ #
+ # def dashboard
+ # @dashboard ||= Dashboard.new
+ # end
+ # end
+ #
+ # class Dashboard
+ # def refresh(transition)
+ # # ...
+ # end
+ # end
+ #
+ # In the above example, Dashboard#refresh *must* defined a
+ # +transition+ argument. Otherwise, an +ArgumentError+ exception will get
+ # raised. The only way around this is to avoid the use of delegates and
+ # manually define the delegate method so that the correct arity is used.
+ #
+ # == Examples
+ #
+ # Below is an example of a class with one state machine and various types
+ # of +before+ transitions defined for it:
+ #
+ # class Vehicle
+ # state_machine do
+ # # Before all transitions
+ # before_transition :update_dashboard
+ #
+ # # Before specific transition:
+ # before_transition [:first_gear, :idling] => :parked, :on => :park, :do => :take_off_seatbelt
+ #
+ # # With conditional callback:
+ # before_transition all => :parked, :do => :take_off_seatbelt, :if => :seatbelt_on?
+ #
+ # # Using helpers:
+ # before_transition all - :stalled => same, :on => any - :crash, :do => :update_dashboard
+ # ...
+ # end
+ # end
+ #
+ # As can be seen, any number of transitions can be created using various
+ # combinations of configuration options.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1643
+ def before_transition(*args, &block); end
+
+ # The callbacks to invoke before/after a transition is performed
+ #
+ # Maps :before => callbacks and :after => callbacks
+ #
+ # source://state_machines//lib/state_machines/machine.rb#489
+ def callbacks; end
+
+ # Defines a new helper method in an instance or class scope with the given
+ # name. If the method is already defined in the scope, then this will not
+ # override it.
+ #
+ # If passing in a block, there are two side effects to be aware of
+ # 1. The method cannot be chained, meaning that the block cannot call +super+
+ # 2. If the method is already defined in an ancestor, then it will not get
+ # overridden and a warning will be output.
+ #
+ # Example:
+ #
+ # # Instance helper
+ # machine.define_helper(:instance, :state_name) do |machine, object|
+ # machine.states.match(object).name
+ # end
+ #
+ # # Class helper
+ # machine.define_helper(:class, :state_machine_name) do |machine, klass|
+ # "State"
+ # end
+ #
+ # You can also define helpers using string evaluation like so:
+ #
+ # # Instance helper
+ # machine.define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
+ # def state_name
+ # self.class.state_machine(:state).states.match(self).name
+ # end
+ # end_eval
+ #
+ # # Class helper
+ # machine.define_helper :class, <<-end_eval, __FILE__, __LINE__ + 1
+ # def state_machine_name
+ # "State"
+ # end
+ # end_eval
+ #
+ # source://state_machines//lib/state_machines/machine.rb#718
+ def define_helper(scope, method, *args, **kwargs, &block); end
+
+ # source://state_machines//lib/state_machines/machine.rb#1877
+ def draw(*_arg0); end
+
+ # Whether a dynamic initial state is being used in the machine
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#651
+ def dynamic_initial_state?; end
+
+ # Gets a description of the errors for the given object. This is used to
+ # provide more detailed information when an InvalidTransition exception is
+ # raised.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1839
+ def errors_for(_object); end
+
+ # Defines one or more events for the machine and the transitions that can
+ # be performed when those events are run.
+ #
+ # This method is also aliased as +on+ for improved compatibility with
+ # using a domain-specific language.
+ #
+ # Configuration options:
+ # * :human_name - The human-readable version of this event's name.
+ # By default, this is either defined by the integration or stringifies the
+ # name and converts underscores to spaces.
+ #
+ # == Instance methods
+ #
+ # The following instance methods are generated when a new event is defined
+ # (the "park" event is used as an example):
+ # * park(..., run_action = true) - Fires the "park" event,
+ # transitioning from the current state to the next valid state. If the
+ # last argument is a boolean, it will control whether the machine's action
+ # gets run.
+ # * park!(..., run_action = true) - Fires the "park" event,
+ # transitioning from the current state to the next valid state. If the
+ # transition fails, then a StateMachines::InvalidTransition error will be
+ # raised. If the last argument is a boolean, it will control whether the
+ # machine's action gets run.
+ # * can_park?(requirements = {}) - Checks whether the "park" event
+ # can be fired given the current state of the object. This will *not* run
+ # validations or callbacks in ORM integrations. It will only determine if
+ # the state machine defines a valid transition for the event. To check
+ # whether an event can fire *and* passes validations, use event attributes
+ # (e.g. state_event) as described in the "Events" documentation of each
+ # ORM integration.
+ # * park_transition(requirements = {}) - Gets the next transition
+ # that would be performed if the "park" event were to be fired now on the
+ # object or nil if no transitions can be performed. Like can_park?
+ # this will also *not* run validations or callbacks. It will only
+ # determine if the state machine defines a valid transition for the event.
+ #
+ # With a namespace of "car", the above names map to the following methods:
+ # * can_park_car?
+ # * park_car_transition
+ # * park_car
+ # * park_car!
+ #
+ # The can_park? and park_transition helpers both take an
+ # optional set of requirements for determining what transitions are available
+ # for the current object. These requirements include:
+ # * :from - One or more states to transition from. If none are
+ # specified, then this will be the object's current state.
+ # * :to - One or more states to transition to. If none are
+ # specified, then this will match any to state.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # == Defining transitions
+ #
+ # +event+ requires a block which allows you to define the possible
+ # transitions that can happen as a result of that event. For example,
+ #
+ # event :park, :stop do
+ # transition :idling => :parked
+ # end
+ #
+ # event :first_gear do
+ # transition :parked => :first_gear, :if => :seatbelt_on?
+ # transition :parked => same # Allow to loopback if seatbelt is off
+ # end
+ #
+ # See StateMachines::Event#transition for more information on
+ # the possible options that can be passed in.
+ #
+ # *Note* that this block is executed within the context of the actual event
+ # object. As a result, you will not be able to reference any class methods
+ # on the model without referencing the class itself. For example,
+ #
+ # class Vehicle
+ # def self.safe_states
+ # [:parked, :idling, :stalled]
+ # end
+ #
+ # state_machine do
+ # event :park do
+ # transition Vehicle.safe_states => :parked
+ # end
+ # end
+ # end
+ #
+ # == Overriding the event method
+ #
+ # By default, this will define an instance method (with the same name as the
+ # event) that will fire the next possible transition for that. Although the
+ # +before_transition+, +after_transition+, and +around_transition+ hooks
+ # allow you to define behavior that gets executed as a result of the event's
+ # transition, you can also override the event method in order to have a
+ # little more fine-grained control.
+ #
+ # For example:
+ #
+ # class Vehicle
+ # state_machine do
+ # event :park do
+ # ...
+ # end
+ # end
+ #
+ # def park(*)
+ # take_deep_breath # Executes before the transition (and before_transition hooks) even if no transition is possible
+ # if result = super # Runs the transition and all before/after/around hooks
+ # applaud # Executes after the transition (and after_transition hooks)
+ # end
+ # result
+ # end
+ # end
+ #
+ # There are a few important things to note here. First, the method
+ # signature is defined with an unlimited argument list in order to allow
+ # callers to continue passing arguments that are expected by state_machine.
+ # For example, it will still allow calls to +park+ with a single parameter
+ # for skipping the configured action.
+ #
+ # Second, the overridden event method must call +super+ in order to run the
+ # logic for running the next possible transition. In order to remain
+ # consistent with other events, the result of +super+ is returned.
+ #
+ # Third, any behavior defined in this method will *not* get executed if
+ # you're taking advantage of attribute-based event transitions. For example:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.state_event = 'park'
+ # vehicle.save
+ #
+ # In this case, the +park+ event will run the before/after/around transition
+ # hooks and transition the state, but the behavior defined in the overriden
+ # +park+ method will *not* be executed.
+ #
+ # == Defining additional arguments
+ #
+ # Additional arguments can be passed into events and accessed by transition
+ # hooks like so:
+ #
+ # class Vehicle
+ # state_machine do
+ # after_transition :on => :park do |vehicle, transition|
+ # kind = *transition.args # :parallel
+ # ...
+ # end
+ # after_transition :on => :park, :do => :take_deep_breath
+ #
+ # event :park do
+ # ...
+ # end
+ #
+ # def take_deep_breath(transition)
+ # kind = *transition.args # :parallel
+ # ...
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # vehicle.park(:parallel)
+ #
+ # *Remember* that if the last argument is a boolean, it will be used as the
+ # +run_action+ parameter to the event action. Using the +park+ action
+ # example from above, you can might call it like so:
+ #
+ # vehicle.park # => Uses default args and runs machine action
+ # vehicle.park(:parallel) # => Specifies the +kind+ argument and runs the machine action
+ # vehicle.park(:parallel, false) # => Specifies the +kind+ argument and *skips* the machine action
+ #
+ # If you decide to override the +park+ event method *and* define additional
+ # arguments, you can do so as shown below:
+ #
+ # class Vehicle
+ # state_machine do
+ # event :park do
+ # ...
+ # end
+ # end
+ #
+ # def park(kind = :parallel, *args)
+ # take_deep_breath if kind == :parallel
+ # super
+ # end
+ # end
+ #
+ # Note that +super+ is called instead of super(*args). This allow
+ # the entire arguments list to be accessed by transition callbacks through
+ # StateMachines::Transition#args.
+ #
+ # === Using matchers
+ #
+ # The +all+ / +any+ matchers can be used to easily execute blocks for a
+ # group of events. Note, however, that you cannot use these matchers to
+ # set configurations for events. Blocks using these matchers can be
+ # defined at any point in the state machine and will always get applied to
+ # the proper events.
+ #
+ # For example:
+ #
+ # state_machine :initial => :parked do
+ # ...
+ #
+ # event all - [:crash] do
+ # transition :stalled => :parked
+ # end
+ # end
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine do
+ # # The park, stop, and halt events will all share the given transitions
+ # event :park, :stop, :halt do
+ # transition [:idling, :backing_up] => :parked
+ # end
+ #
+ # event :stop do
+ # transition :first_gear => :idling
+ # end
+ #
+ # event :ignite do
+ # transition :parked => :idling
+ # transition :idling => same # Allow ignite while still idling
+ # end
+ # end
+ # end
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1308
+ def event(*names, &block); end
+
+ # The events that trigger transitions. These are sorted, by default, in
+ # the order in which they were defined.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#473
+ def events; end
+
+ # Generates the message to use when invalidating the given object after
+ # failing to transition on a specific event
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1851
+ def generate_message(name, values = T.unsafe(nil)); end
+
+ # Gets the initial state of the machine for the given object. If a dynamic
+ # initial state was configured for this machine, then the object will be
+ # passed into the lambda block to help determine the actual state.
+ #
+ # == Examples
+ #
+ # With a static initial state:
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # Vehicle.state_machine.initial_state(vehicle) # => #
+ #
+ # With a dynamic initial state:
+ #
+ # class Vehicle
+ # attr_accessor :force_idle
+ #
+ # state_machine :initial => lambda {|vehicle| vehicle.force_idle ? :idling : :parked} do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ #
+ # vehicle.force_idle = true
+ # Vehicle.state_machine.initial_state(vehicle) # => #
+ #
+ # vehicle.force_idle = false
+ # Vehicle.state_machine.initial_state(vehicle) # => #
+ #
+ # source://state_machines//lib/state_machines/machine.rb#646
+ def initial_state(object); end
+
+ # Sets the initial state of the machine. This can be either the static name
+ # of a state or a lambda block which determines the initial state at
+ # creation time.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#593
+ def initial_state=(new_initial_state); end
+
+ # Initializes the state on the given object. Initial values are only set if
+ # the machine's attribute hasn't been previously initialized.
+ #
+ # Configuration options:
+ # * :force - Whether to initialize the state regardless of its
+ # current value
+ # * :to - A hash to set the initial value in instead of writing
+ # directly to the object
+ #
+ # source://state_machines//lib/state_machines/machine.rb#663
+ def initialize_state(object, options = T.unsafe(nil)); end
+
+ # Marks the given object as invalid with the given message.
+ #
+ # By default, this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1833
+ def invalidate(_object, _attribute, _message, _values = T.unsafe(nil)); end
+
+ # The name of the machine, used for scoping methods generated for the
+ # machine as a whole (not states or events)
+ #
+ # source://state_machines//lib/state_machines/machine.rb#469
+ def name; end
+
+ # An identifier that forces all methods (including state predicates and
+ # event methods) to be generated with the value prefixed or suffixed,
+ # depending on the context.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#497
+ def namespace; end
+
+ # Defines one or more events for the machine and the transitions that can
+ # be performed when those events are run.
+ #
+ # This method is also aliased as +on+ for improved compatibility with
+ # using a domain-specific language.
+ #
+ # Configuration options:
+ # * :human_name - The human-readable version of this event's name.
+ # By default, this is either defined by the integration or stringifies the
+ # name and converts underscores to spaces.
+ #
+ # == Instance methods
+ #
+ # The following instance methods are generated when a new event is defined
+ # (the "park" event is used as an example):
+ # * park(..., run_action = true) - Fires the "park" event,
+ # transitioning from the current state to the next valid state. If the
+ # last argument is a boolean, it will control whether the machine's action
+ # gets run.
+ # * park!(..., run_action = true) - Fires the "park" event,
+ # transitioning from the current state to the next valid state. If the
+ # transition fails, then a StateMachines::InvalidTransition error will be
+ # raised. If the last argument is a boolean, it will control whether the
+ # machine's action gets run.
+ # * can_park?(requirements = {}) - Checks whether the "park" event
+ # can be fired given the current state of the object. This will *not* run
+ # validations or callbacks in ORM integrations. It will only determine if
+ # the state machine defines a valid transition for the event. To check
+ # whether an event can fire *and* passes validations, use event attributes
+ # (e.g. state_event) as described in the "Events" documentation of each
+ # ORM integration.
+ # * park_transition(requirements = {}) - Gets the next transition
+ # that would be performed if the "park" event were to be fired now on the
+ # object or nil if no transitions can be performed. Like can_park?
+ # this will also *not* run validations or callbacks. It will only
+ # determine if the state machine defines a valid transition for the event.
+ #
+ # With a namespace of "car", the above names map to the following methods:
+ # * can_park_car?
+ # * park_car_transition
+ # * park_car
+ # * park_car!
+ #
+ # The can_park? and park_transition helpers both take an
+ # optional set of requirements for determining what transitions are available
+ # for the current object. These requirements include:
+ # * :from - One or more states to transition from. If none are
+ # specified, then this will be the object's current state.
+ # * :to - One or more states to transition to. If none are
+ # specified, then this will match any to state.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # == Defining transitions
+ #
+ # +event+ requires a block which allows you to define the possible
+ # transitions that can happen as a result of that event. For example,
+ #
+ # event :park, :stop do
+ # transition :idling => :parked
+ # end
+ #
+ # event :first_gear do
+ # transition :parked => :first_gear, :if => :seatbelt_on?
+ # transition :parked => same # Allow to loopback if seatbelt is off
+ # end
+ #
+ # See StateMachines::Event#transition for more information on
+ # the possible options that can be passed in.
+ #
+ # *Note* that this block is executed within the context of the actual event
+ # object. As a result, you will not be able to reference any class methods
+ # on the model without referencing the class itself. For example,
+ #
+ # class Vehicle
+ # def self.safe_states
+ # [:parked, :idling, :stalled]
+ # end
+ #
+ # state_machine do
+ # event :park do
+ # transition Vehicle.safe_states => :parked
+ # end
+ # end
+ # end
+ #
+ # == Overriding the event method
+ #
+ # By default, this will define an instance method (with the same name as the
+ # event) that will fire the next possible transition for that. Although the
+ # +before_transition+, +after_transition+, and +around_transition+ hooks
+ # allow you to define behavior that gets executed as a result of the event's
+ # transition, you can also override the event method in order to have a
+ # little more fine-grained control.
+ #
+ # For example:
+ #
+ # class Vehicle
+ # state_machine do
+ # event :park do
+ # ...
+ # end
+ # end
+ #
+ # def park(*)
+ # take_deep_breath # Executes before the transition (and before_transition hooks) even if no transition is possible
+ # if result = super # Runs the transition and all before/after/around hooks
+ # applaud # Executes after the transition (and after_transition hooks)
+ # end
+ # result
+ # end
+ # end
+ #
+ # There are a few important things to note here. First, the method
+ # signature is defined with an unlimited argument list in order to allow
+ # callers to continue passing arguments that are expected by state_machine.
+ # For example, it will still allow calls to +park+ with a single parameter
+ # for skipping the configured action.
+ #
+ # Second, the overridden event method must call +super+ in order to run the
+ # logic for running the next possible transition. In order to remain
+ # consistent with other events, the result of +super+ is returned.
+ #
+ # Third, any behavior defined in this method will *not* get executed if
+ # you're taking advantage of attribute-based event transitions. For example:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.state_event = 'park'
+ # vehicle.save
+ #
+ # In this case, the +park+ event will run the before/after/around transition
+ # hooks and transition the state, but the behavior defined in the overriden
+ # +park+ method will *not* be executed.
+ #
+ # == Defining additional arguments
+ #
+ # Additional arguments can be passed into events and accessed by transition
+ # hooks like so:
+ #
+ # class Vehicle
+ # state_machine do
+ # after_transition :on => :park do |vehicle, transition|
+ # kind = *transition.args # :parallel
+ # ...
+ # end
+ # after_transition :on => :park, :do => :take_deep_breath
+ #
+ # event :park do
+ # ...
+ # end
+ #
+ # def take_deep_breath(transition)
+ # kind = *transition.args # :parallel
+ # ...
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # vehicle.park(:parallel)
+ #
+ # *Remember* that if the last argument is a boolean, it will be used as the
+ # +run_action+ parameter to the event action. Using the +park+ action
+ # example from above, you can might call it like so:
+ #
+ # vehicle.park # => Uses default args and runs machine action
+ # vehicle.park(:parallel) # => Specifies the +kind+ argument and runs the machine action
+ # vehicle.park(:parallel, false) # => Specifies the +kind+ argument and *skips* the machine action
+ #
+ # If you decide to override the +park+ event method *and* define additional
+ # arguments, you can do so as shown below:
+ #
+ # class Vehicle
+ # state_machine do
+ # event :park do
+ # ...
+ # end
+ # end
+ #
+ # def park(kind = :parallel, *args)
+ # take_deep_breath if kind == :parallel
+ # super
+ # end
+ # end
+ #
+ # Note that +super+ is called instead of super(*args). This allow
+ # the entire arguments list to be accessed by transition callbacks through
+ # StateMachines::Transition#args.
+ #
+ # === Using matchers
+ #
+ # The +all+ / +any+ matchers can be used to easily execute blocks for a
+ # group of events. Note, however, that you cannot use these matchers to
+ # set configurations for events. Blocks using these matchers can be
+ # defined at any point in the state machine and will always get applied to
+ # the proper events.
+ #
+ # For example:
+ #
+ # state_machine :initial => :parked do
+ # ...
+ #
+ # event all - [:crash] do
+ # transition :stalled => :parked
+ # end
+ # end
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine do
+ # # The park, stop, and halt events will all share the given transitions
+ # event :park, :stop, :halt do
+ # transition [:idling, :backing_up] => :parked
+ # end
+ #
+ # event :stop do
+ # transition :first_gear => :idling
+ # end
+ #
+ # event :ignite do
+ # transition :parked => :idling
+ # transition :idling => same # Allow ignite while still idling
+ # end
+ # end
+ # end
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1308
+ def on(*names, &block); end
+
+ # Customizes the definition of one or more states in the machine.
+ #
+ # Configuration options:
+ # * :value - The actual value to store when an object transitions
+ # to the state. Default is the name (stringified).
+ # * :cache - If a dynamic value (via a lambda block) is being used,
+ # then setting this to true will cache the evaluated result
+ # * :if - Determines whether an object's value matches the state
+ # (e.g. :value => lambda {Time.now}, :if => lambda {|state| !state.nil?}).
+ # By default, the configured value is matched.
+ # * :human_name - The human-readable version of this state's name.
+ # By default, this is either defined by the integration or stringifies the
+ # name and converts underscores to spaces.
+ #
+ # == Customizing the stored value
+ #
+ # Whenever a state is automatically discovered in the state machine, its
+ # default value is assumed to be the stringified version of the name. For
+ # example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # In the above state machine, there are two states automatically discovered:
+ # :parked and :idling. These states, by default, will store their stringified
+ # equivalents when an object moves into that state (e.g. "parked" / "idling").
+ #
+ # For legacy systems or when tying state machines into existing frameworks,
+ # it's oftentimes necessary to need to store a different value for a state
+ # than the default. In order to continue taking advantage of an expressive
+ # state machine and helper methods, every defined state can be re-configured
+ # with a custom stored value. For example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # state :idling, :value => 'IDLING'
+ # state :parked, :value => 'PARKED
+ # end
+ # end
+ #
+ # This is also useful if being used in association with a database and,
+ # instead of storing the state name in a column, you want to store the
+ # state's foreign key:
+ #
+ # class VehicleState < ActiveRecord::Base
+ # end
+ #
+ # class Vehicle < ActiveRecord::Base
+ # state_machine :attribute => :state_id, :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # states.each do |state|
+ # self.state(state.name, :value => lambda { VehicleState.find_by_name(state.name.to_s).id }, :cache => true)
+ # end
+ # end
+ # end
+ #
+ # In the above example, each known state is configured to store it's
+ # associated database id in the +state_id+ attribute. Also, notice that a
+ # lambda block is used to define the state's value. This is required in
+ # situations (like testing) where the model is loaded without any existing
+ # data (i.e. no VehicleState records available).
+ #
+ # One caveat to the above example is to keep performance in mind. To avoid
+ # constant db hits for looking up the VehicleState ids, the value is cached
+ # by specifying the :cache option. Alternatively, a custom
+ # caching strategy can be used like so:
+ #
+ # class VehicleState < ActiveRecord::Base
+ # cattr_accessor :cache_store
+ # self.cache_store = ActiveSupport::Cache::MemoryStore.new
+ #
+ # def self.find_by_name(name)
+ # cache_store.fetch(name) { find(:first, :conditions => {:name => name}) }
+ # end
+ # end
+ #
+ # === Dynamic values
+ #
+ # In addition to customizing states with other value types, lambda blocks
+ # can also be specified to allow for a state's value to be determined
+ # dynamically at runtime. For example,
+ #
+ # class Vehicle
+ # state_machine :purchased_at, :initial => :available do
+ # event :purchase do
+ # transition all => :purchased
+ # end
+ #
+ # event :restock do
+ # transition all => :available
+ # end
+ #
+ # state :available, :value => nil
+ # state :purchased, :if => lambda {|value| !value.nil?}, :value => lambda {Time.now}
+ # end
+ # end
+ #
+ # In the above definition, the :purchased state is customized with
+ # both a dynamic value *and* a value matcher.
+ #
+ # When an object transitions to the purchased state, the value's lambda
+ # block will be called. This will get the current time and store it in the
+ # object's +purchased_at+ attribute.
+ #
+ # *Note* that the custom matcher is very important here. Since there's no
+ # way for the state machine to figure out an object's state when it's set to
+ # a runtime value, it must be explicitly defined. If the :if option
+ # were not configured for the state, then an ArgumentError exception would
+ # be raised at runtime, indicating that the state machine could not figure
+ # out what the current state of the object was.
+ #
+ # == Behaviors
+ #
+ # Behaviors define a series of methods to mixin with objects when the current
+ # state matches the given one(s). This allows instance methods to behave
+ # a specific way depending on what the value of the object's state is.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # attr_accessor :driver
+ # attr_accessor :passenger
+ #
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # state :parked do
+ # def speed
+ # 0
+ # end
+ #
+ # def rotate_driver
+ # driver = self.driver
+ # self.driver = passenger
+ # self.passenger = driver
+ # true
+ # end
+ # end
+ #
+ # state :idling, :first_gear do
+ # def speed
+ # 20
+ # end
+ #
+ # def rotate_driver
+ # self.state = 'parked'
+ # rotate_driver
+ # end
+ # end
+ #
+ # other_states :backing_up
+ # end
+ # end
+ #
+ # In the above example, there are two dynamic behaviors defined for the
+ # class:
+ # * +speed+
+ # * +rotate_driver+
+ #
+ # Each of these behaviors are instance methods on the Vehicle class. However,
+ # which method actually gets invoked is based on the current state of the
+ # object. Using the above class as the example:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.driver = 'John'
+ # vehicle.passenger = 'Jane'
+ #
+ # # Behaviors in the "parked" state
+ # vehicle.state # => "parked"
+ # vehicle.speed # => 0
+ # vehicle.rotate_driver # => true
+ # vehicle.driver # => "Jane"
+ # vehicle.passenger # => "John"
+ #
+ # vehicle.ignite # => true
+ #
+ # # Behaviors in the "idling" state
+ # vehicle.state # => "idling"
+ # vehicle.speed # => 20
+ # vehicle.rotate_driver # => true
+ # vehicle.driver # => "John"
+ # vehicle.passenger # => "Jane"
+ #
+ # As can be seen, both the +speed+ and +rotate_driver+ instance method
+ # implementations changed how they behave based on what the current state
+ # of the vehicle was.
+ #
+ # === Invalid behaviors
+ #
+ # If a specific behavior has not been defined for a state, then a
+ # NoMethodError exception will be raised, indicating that that method would
+ # not normally exist for an object with that state.
+ #
+ # Using the example from before:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.state = 'backing_up'
+ # vehicle.speed # => NoMethodError: undefined method 'speed' for # in state "backing_up"
+ #
+ # === Using matchers
+ #
+ # The +all+ / +any+ matchers can be used to easily define behaviors for a
+ # group of states. Note, however, that you cannot use these matchers to
+ # set configurations for states. Behaviors using these matchers can be
+ # defined at any point in the state machine and will always get applied to
+ # the proper states.
+ #
+ # For example:
+ #
+ # state_machine :initial => :parked do
+ # ...
+ #
+ # state all - [:parked, :idling, :stalled] do
+ # validates_presence_of :speed
+ #
+ # def speed
+ # gear * 10
+ # end
+ # end
+ # end
+ #
+ # == State-aware class methods
+ #
+ # In addition to defining scopes for instance methods that are state-aware,
+ # the same can be done for certain types of class methods.
+ #
+ # Some libraries have support for class-level methods that only run certain
+ # behaviors based on a conditions hash passed in. For example:
+ #
+ # class Vehicle < ActiveRecord::Base
+ # state_machine do
+ # ...
+ # state :first_gear, :second_gear, :third_gear do
+ # validates_presence_of :speed
+ # validates_inclusion_of :speed, :in => 0..25, :if => :in_school_zone?
+ # end
+ # end
+ # end
+ #
+ # In the above ActiveRecord model, two validations have been defined which
+ # will *only* run when the Vehicle object is in one of the three states:
+ # +first_gear+, +second_gear+, or +third_gear. Notice, also, that if/unless
+ # conditions can continue to be used.
+ #
+ # This functionality is not library-specific and can work for any class-level
+ # method that is defined like so:
+ #
+ # def validates_presence_of(attribute, options = {})
+ # ...
+ # end
+ #
+ # The minimum requirement is that the last argument in the method be an
+ # options hash which contains at least :if condition support.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1005
+ def other_states(*names, &block); end
+
+ # The class that the machine is defined in
+ #
+ # source://state_machines//lib/state_machines/machine.rb#465
+ def owner_class; end
+
+ # Sets the class which is the owner of this state machine. Any methods
+ # generated by states, events, or other parts of the machine will be defined
+ # on the given owner class.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#565
+ def owner_class=(klass); end
+
+ # Generates a list of the possible transition sequences that can be run on
+ # the given object. These paths can reveal all of the possible states and
+ # events that can be encountered in the object's state machine based on the
+ # object's current state.
+ #
+ # Configuration options:
+ # * +from+ - The initial state to start all paths from. By default, this
+ # is the object's current state.
+ # * +to+ - The target state to end all paths on. By default, paths will
+ # end when they loop back to the first transition on the path.
+ # * +deep+ - Whether to allow the target state to be crossed more than once
+ # in a path. By default, paths will immediately stop when the target
+ # state (if specified) is reached. If this is enabled, then paths can
+ # continue even after reaching the target state; they will stop when
+ # reaching the target state a second time.
+ #
+ # *Note* that the object is never modified when the list of paths is
+ # generated.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # event :shift_up do
+ # transition :idling => :first_gear, :first_gear => :second_gear
+ # end
+ #
+ # event :shift_down do
+ # transition :second_gear => :first_gear, :first_gear => :idling
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ #
+ # vehicle.state_paths
+ # # => [
+ # # [#,
+ # # #,
+ # # #,
+ # # #,
+ # # #],
+ # #
+ # # [#,
+ # # #,
+ # # #]
+ # # ]
+ #
+ # vehicle.state_paths(:from => :parked, :to => :second_gear)
+ # # => [
+ # # [#,
+ # # #,
+ # # #]
+ # # ]
+ #
+ # In addition to getting the possible paths that can be accessed, you can
+ # also get summary information about the states / events that can be
+ # accessed at some point along one of the paths. For example:
+ #
+ # # Get the list of states that can be accessed from the current state
+ # vehicle.state_paths.to_states # => [:idling, :first_gear, :second_gear]
+ #
+ # # Get the list of events that can be accessed from the current state
+ # vehicle.state_paths.events # => [:ignite, :shift_up, :shift_down]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1826
+ def paths_for(object, requirements = T.unsafe(nil)); end
+
+ # Gets the current value stored in the given object's attribute.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # Vehicle.state_machine.read(vehicle, :state) # => "parked" # Equivalent to vehicle.state
+ # Vehicle.state_machine.read(vehicle, :event) # => nil # Equivalent to vehicle.state_event
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1053
+ def read(object, attribute, ivar = T.unsafe(nil)); end
+
+ # Resets any errors previously added when invalidating the given object.
+ #
+ # By default, this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1846
+ def reset(_object); end
+
+ # Customizes the definition of one or more states in the machine.
+ #
+ # Configuration options:
+ # * :value - The actual value to store when an object transitions
+ # to the state. Default is the name (stringified).
+ # * :cache - If a dynamic value (via a lambda block) is being used,
+ # then setting this to true will cache the evaluated result
+ # * :if - Determines whether an object's value matches the state
+ # (e.g. :value => lambda {Time.now}, :if => lambda {|state| !state.nil?}).
+ # By default, the configured value is matched.
+ # * :human_name - The human-readable version of this state's name.
+ # By default, this is either defined by the integration or stringifies the
+ # name and converts underscores to spaces.
+ #
+ # == Customizing the stored value
+ #
+ # Whenever a state is automatically discovered in the state machine, its
+ # default value is assumed to be the stringified version of the name. For
+ # example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # In the above state machine, there are two states automatically discovered:
+ # :parked and :idling. These states, by default, will store their stringified
+ # equivalents when an object moves into that state (e.g. "parked" / "idling").
+ #
+ # For legacy systems or when tying state machines into existing frameworks,
+ # it's oftentimes necessary to need to store a different value for a state
+ # than the default. In order to continue taking advantage of an expressive
+ # state machine and helper methods, every defined state can be re-configured
+ # with a custom stored value. For example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # state :idling, :value => 'IDLING'
+ # state :parked, :value => 'PARKED
+ # end
+ # end
+ #
+ # This is also useful if being used in association with a database and,
+ # instead of storing the state name in a column, you want to store the
+ # state's foreign key:
+ #
+ # class VehicleState < ActiveRecord::Base
+ # end
+ #
+ # class Vehicle < ActiveRecord::Base
+ # state_machine :attribute => :state_id, :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # states.each do |state|
+ # self.state(state.name, :value => lambda { VehicleState.find_by_name(state.name.to_s).id }, :cache => true)
+ # end
+ # end
+ # end
+ #
+ # In the above example, each known state is configured to store it's
+ # associated database id in the +state_id+ attribute. Also, notice that a
+ # lambda block is used to define the state's value. This is required in
+ # situations (like testing) where the model is loaded without any existing
+ # data (i.e. no VehicleState records available).
+ #
+ # One caveat to the above example is to keep performance in mind. To avoid
+ # constant db hits for looking up the VehicleState ids, the value is cached
+ # by specifying the :cache option. Alternatively, a custom
+ # caching strategy can be used like so:
+ #
+ # class VehicleState < ActiveRecord::Base
+ # cattr_accessor :cache_store
+ # self.cache_store = ActiveSupport::Cache::MemoryStore.new
+ #
+ # def self.find_by_name(name)
+ # cache_store.fetch(name) { find(:first, :conditions => {:name => name}) }
+ # end
+ # end
+ #
+ # === Dynamic values
+ #
+ # In addition to customizing states with other value types, lambda blocks
+ # can also be specified to allow for a state's value to be determined
+ # dynamically at runtime. For example,
+ #
+ # class Vehicle
+ # state_machine :purchased_at, :initial => :available do
+ # event :purchase do
+ # transition all => :purchased
+ # end
+ #
+ # event :restock do
+ # transition all => :available
+ # end
+ #
+ # state :available, :value => nil
+ # state :purchased, :if => lambda {|value| !value.nil?}, :value => lambda {Time.now}
+ # end
+ # end
+ #
+ # In the above definition, the :purchased state is customized with
+ # both a dynamic value *and* a value matcher.
+ #
+ # When an object transitions to the purchased state, the value's lambda
+ # block will be called. This will get the current time and store it in the
+ # object's +purchased_at+ attribute.
+ #
+ # *Note* that the custom matcher is very important here. Since there's no
+ # way for the state machine to figure out an object's state when it's set to
+ # a runtime value, it must be explicitly defined. If the :if option
+ # were not configured for the state, then an ArgumentError exception would
+ # be raised at runtime, indicating that the state machine could not figure
+ # out what the current state of the object was.
+ #
+ # == Behaviors
+ #
+ # Behaviors define a series of methods to mixin with objects when the current
+ # state matches the given one(s). This allows instance methods to behave
+ # a specific way depending on what the value of the object's state is.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # attr_accessor :driver
+ # attr_accessor :passenger
+ #
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # state :parked do
+ # def speed
+ # 0
+ # end
+ #
+ # def rotate_driver
+ # driver = self.driver
+ # self.driver = passenger
+ # self.passenger = driver
+ # true
+ # end
+ # end
+ #
+ # state :idling, :first_gear do
+ # def speed
+ # 20
+ # end
+ #
+ # def rotate_driver
+ # self.state = 'parked'
+ # rotate_driver
+ # end
+ # end
+ #
+ # other_states :backing_up
+ # end
+ # end
+ #
+ # In the above example, there are two dynamic behaviors defined for the
+ # class:
+ # * +speed+
+ # * +rotate_driver+
+ #
+ # Each of these behaviors are instance methods on the Vehicle class. However,
+ # which method actually gets invoked is based on the current state of the
+ # object. Using the above class as the example:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.driver = 'John'
+ # vehicle.passenger = 'Jane'
+ #
+ # # Behaviors in the "parked" state
+ # vehicle.state # => "parked"
+ # vehicle.speed # => 0
+ # vehicle.rotate_driver # => true
+ # vehicle.driver # => "Jane"
+ # vehicle.passenger # => "John"
+ #
+ # vehicle.ignite # => true
+ #
+ # # Behaviors in the "idling" state
+ # vehicle.state # => "idling"
+ # vehicle.speed # => 20
+ # vehicle.rotate_driver # => true
+ # vehicle.driver # => "John"
+ # vehicle.passenger # => "Jane"
+ #
+ # As can be seen, both the +speed+ and +rotate_driver+ instance method
+ # implementations changed how they behave based on what the current state
+ # of the vehicle was.
+ #
+ # === Invalid behaviors
+ #
+ # If a specific behavior has not been defined for a state, then a
+ # NoMethodError exception will be raised, indicating that that method would
+ # not normally exist for an object with that state.
+ #
+ # Using the example from before:
+ #
+ # vehicle = Vehicle.new
+ # vehicle.state = 'backing_up'
+ # vehicle.speed # => NoMethodError: undefined method 'speed' for # in state "backing_up"
+ #
+ # === Using matchers
+ #
+ # The +all+ / +any+ matchers can be used to easily define behaviors for a
+ # group of states. Note, however, that you cannot use these matchers to
+ # set configurations for states. Behaviors using these matchers can be
+ # defined at any point in the state machine and will always get applied to
+ # the proper states.
+ #
+ # For example:
+ #
+ # state_machine :initial => :parked do
+ # ...
+ #
+ # state all - [:parked, :idling, :stalled] do
+ # validates_presence_of :speed
+ #
+ # def speed
+ # gear * 10
+ # end
+ # end
+ # end
+ #
+ # == State-aware class methods
+ #
+ # In addition to defining scopes for instance methods that are state-aware,
+ # the same can be done for certain types of class methods.
+ #
+ # Some libraries have support for class-level methods that only run certain
+ # behaviors based on a conditions hash passed in. For example:
+ #
+ # class Vehicle < ActiveRecord::Base
+ # state_machine do
+ # ...
+ # state :first_gear, :second_gear, :third_gear do
+ # validates_presence_of :speed
+ # validates_inclusion_of :speed, :in => 0..25, :if => :in_school_zone?
+ # end
+ # end
+ # end
+ #
+ # In the above ActiveRecord model, two validations have been defined which
+ # will *only* run when the Vehicle object is in one of the three states:
+ # +first_gear+, +second_gear+, or +third_gear. Notice, also, that if/unless
+ # conditions can continue to be used.
+ #
+ # This functionality is not library-specific and can work for any class-level
+ # method that is defined like so:
+ #
+ # def validates_presence_of(attribute, options = {})
+ # ...
+ # end
+ #
+ # The minimum requirement is that the last argument in the method be an
+ # options hash which contains at least :if condition support.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1005
+ def state(*names, &block); end
+
+ # A list of all of the states known to this state machine. This will pull
+ # states from the following sources:
+ # * Initial state
+ # * State behaviors
+ # * Event transitions (:to, :from, and :except_from options)
+ # * Transition callbacks (:to, :from, :except_to, and :except_from options)
+ # * Unreferenced states (using +other_states+ helper)
+ #
+ # These are sorted, by default, in the order in which they were referenced.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#484
+ def states; end
+
+ # Creates a new transition that determines what to change the current state
+ # to when an event fires.
+ #
+ # == Defining transitions
+ #
+ # The options for a new transition uses the Hash syntax to map beginning
+ # states to ending states. For example,
+ #
+ # transition :parked => :idling, :idling => :first_gear, :on => :ignite
+ #
+ # In this case, when the +ignite+ event is fired, this transition will cause
+ # the state to be +idling+ if it's current state is +parked+ or +first_gear+
+ # if it's current state is +idling+.
+ #
+ # To help define these implicit transitions, a set of helpers are available
+ # for slightly more complex matching:
+ # * all - Matches every state in the machine
+ # * all - [:parked, :idling, ...] - Matches every state except those specified
+ # * any - An alias for +all+ (matches every state in the machine)
+ # * same - Matches the same state being transitioned from
+ #
+ # See StateMachines::MatcherHelpers for more information.
+ #
+ # Examples:
+ #
+ # transition all => nil, :on => :ignite # Transitions to nil regardless of the current state
+ # transition all => :idling, :on => :ignite # Transitions to :idling regardless of the current state
+ # transition all - [:idling, :first_gear] => :idling, :on => :ignite # Transitions every state but :idling and :first_gear to :idling
+ # transition nil => :idling, :on => :ignite # Transitions to :idling from the nil state
+ # transition :parked => :idling, :on => :ignite # Transitions to :idling if :parked
+ # transition [:parked, :stalled] => :idling, :on => :ignite # Transitions to :idling if :parked or :stalled
+ #
+ # transition :parked => same, :on => :park # Loops :parked back to :parked
+ # transition [:parked, :stalled] => same, :on => [:park, :stall] # Loops either :parked or :stalled back to the same state on the park and stall events
+ # transition all - :parked => same, :on => :noop # Loops every state but :parked back to the same state
+ #
+ # # Transitions to :idling if :parked, :first_gear if :idling, or :second_gear if :first_gear
+ # transition :parked => :idling, :idling => :first_gear, :first_gear => :second_gear, :on => :shift_up
+ #
+ # == Verbose transitions
+ #
+ # Transitions can also be defined use an explicit set of configuration
+ # options:
+ # * :from - A state or array of states that can be transitioned from.
+ # If not specified, then the transition can occur for *any* state.
+ # * :to - The state that's being transitioned to. If not specified,
+ # then the transition will simply loop back (i.e. the state will not change).
+ # * :except_from - A state or array of states that *cannot* be
+ # transitioned from.
+ #
+ # These options must be used when defining transitions within the context
+ # of a state.
+ #
+ # Examples:
+ #
+ # transition :to => nil, :on => :park
+ # transition :to => :idling, :on => :ignite
+ # transition :except_from => [:idling, :first_gear], :to => :idling, :on => :ignite
+ # transition :from => nil, :to => :idling, :on => :ignite
+ # transition :from => [:parked, :stalled], :to => :idling, :on => :ignite
+ #
+ # == Conditions
+ #
+ # In addition to the state requirements for each transition, a condition
+ # can also be defined to help determine whether that transition is
+ # available. These options will work on both the normal and verbose syntax.
+ #
+ # Configuration options:
+ # * :if - A method, proc or string to call to determine if the
+ # transition should occur (e.g. :if => :moving?, or :if => lambda {|vehicle| vehicle.speed > 60}).
+ # The condition should return or evaluate to true or false.
+ # * :unless - A method, proc or string to call to determine if the
+ # transition should not occur (e.g. :unless => :stopped?, or :unless => lambda {|vehicle| vehicle.speed <= 60}).
+ # The condition should return or evaluate to true or false.
+ #
+ # Examples:
+ #
+ # transition :parked => :idling, :on => :ignite, :if => :moving?
+ # transition :parked => :idling, :on => :ignite, :unless => :stopped?
+ # transition :idling => :first_gear, :first_gear => :second_gear, :on => :shift_up, :if => :seatbelt_on?
+ #
+ # transition :from => :parked, :to => :idling, :on => ignite, :if => :moving?
+ # transition :from => :parked, :to => :idling, :on => ignite, :unless => :stopped?
+ #
+ # == Order of operations
+ #
+ # Transitions are evaluated in the order in which they're defined. As a
+ # result, if more than one transition applies to a given object, then the
+ # first transition that matches will be performed.
+ #
+ # @raise [ArgumentError]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1428
+ def transition(options); end
+
+ # Whether the machine will use transactions when firing events
+ #
+ # source://state_machines//lib/state_machines/machine.rb#500
+ def use_transactions; end
+
+ # Runs a transaction, rolling back any changes if the yielded block fails.
+ #
+ # This is only applicable to integrations that involve databases. By
+ # default, this will not run any transactions since the changes aren't
+ # taking place within the context of a database.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1868
+ def within_transaction(object); end
+
+ # Sets a new value in the given object's attribute.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # Vehicle.state_machine.write(vehicle, :state, 'idling') # => Equivalent to vehicle.state = 'idling'
+ # Vehicle.state_machine.write(vehicle, :event, 'park') # => Equivalent to vehicle.state_event = 'park'
+ # vehicle.state # => "idling"
+ # vehicle.event # => "park"
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1077
+ def write(object, attribute, value, ivar = T.unsafe(nil)); end
+
+ protected
+
+ # The method to hook into for triggering transitions when invoked. By
+ # default, this is the action configured for the machine.
+ #
+ # Since the default hook technique relies on module inheritance, the
+ # action must be defined in an ancestor of the owner classs in order for
+ # it to be the action hook.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2047
+ def action_hook; end
+
+ # Adds a new transition callback of the given type.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2192
+ def add_callback(type, options, &block); end
+
+ # Tracks the given set of events in the list of all known events for
+ # this machine
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2221
+ def add_events(new_events); end
+
+ # Updates this machine based on the configuration of other machines in the
+ # owner class that share the same target attribute.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2184
+ def add_sibling_machine_configs; end
+
+ # Tracks the given set of states in the list of all known states for
+ # this machine
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2200
+ def add_states(new_states); end
+
+ # Runs additional initialization hooks. By default, this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1890
+ def after_initialize; end
+
+ # Creates a scope for finding objects *with* a particular value or values
+ # for the attribute.
+ #
+ # By default, this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2155
+ def create_with_scope(name); end
+
+ # Creates a scope for finding objects *without* a particular value or
+ # values for the attribute.
+ #
+ # By default, this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2162
+ def create_without_scope(name); end
+
+ # Adds helper methods for automatically firing events when an action
+ # is invoked
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2016
+ def define_action_helpers; end
+
+ # Determines whether action helpers should be defined for this machine.
+ # This is only true if there is an action configured and no other machines
+ # have process this same configuration already.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2010
+ def define_action_helpers?; end
+
+ # Hooks directly into actions by defining the same method in an included
+ # module. As a result, when the action gets invoked, any state events
+ # defined for the object will get run. Method visibility is preserved.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2026
+ def define_action_hook; end
+
+ # Adds helper methods for getting information about this state machine's
+ # events
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1958
+ def define_event_helpers; end
+
+ # Adds helper methods for interacting with the state machine, including
+ # for states, events, and transitions
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1917
+ def define_helpers; end
+
+ # Adds helper methods for accessing naming information about states and
+ # events on the owner class
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2088
+ def define_name_helpers; end
+
+ # Adds helper methods for getting information about this state machine's
+ # available transition paths
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2000
+ def define_path_helpers; end
+
+ # Defines the with/without scope helpers for this attribute. Both the
+ # singular and plural versions of the attribute are defined for each
+ # scope helper. A custom plural can be specified if it cannot be
+ # automatically determined by either calling +pluralize+ on the attribute
+ # name or adding an "s" to the end of the name.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2115
+ def define_scopes(custom_plural = T.unsafe(nil)); end
+
+ # Adds reader/writer methods for accessing the state attribute
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1938
+ def define_state_accessor; end
+
+ # Defines the initial values for state machine attributes. Static values
+ # are set prior to the original initialize method and dynamic values are
+ # set *after* the initialize method in case it is dependent on it.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1929
+ def define_state_initializer; end
+
+ # Adds predicate method to the owner class for determining the name of the
+ # current state
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1947
+ def define_state_predicate; end
+
+ # Determines if the machine's attribute needs to be initialized. This
+ # will only be true if the machine's attribute is blank.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1910
+ def initialize_state?(object); end
+
+ # Determines whether there's already a helper method defined within the
+ # given scope. This is true only if one of the owner's ancestors defines
+ # the method and is further along in the ancestor chain than this
+ # machine's helper module.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2055
+ def owner_class_ancestor_has_method?(scope, method); end
+
+ # Gets the initial attribute value defined by the owner class (outside of
+ # the machine's definition). By default, this is always nil.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2172
+ def owner_class_attribute_default; end
+
+ # Checks whether the given state matches the attribute default specified
+ # by the owner class
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2178
+ def owner_class_attribute_default_matches?(state); end
+
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2081
+ def owner_class_has_method?(scope, method); end
+
+ # Pluralizes the given word using #pluralize (if available) or simply
+ # adding an "s" to the end of the word
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2142
+ def pluralize(word); end
+
+ # Generates the results for the given scope based on one or more states to
+ # filter by
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2135
+ def run_scope(scope, machine, klass, states); end
+
+ # Looks up other machines that have been defined in the owner class and
+ # are targeting the same attribute as this machine. When accessing
+ # sibling machines, they will be automatically copied for the current
+ # class if they haven't been already. This ensures that any configuration
+ # changes made to the sibling machines only affect this class and not any
+ # base class that may have originally defined the machine.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#1899
+ def sibling_machines; end
+
+ # Always yields
+ #
+ # source://state_machines//lib/state_machines/machine.rb#2166
+ def transaction(object); end
+
+ private
+
+ # Creates a copy of this machine in addition to copies of each associated
+ # event/states/callback, so that the modifications to those collections do
+ # not affect the original machine.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#552
+ def initialize_copy(orig); end
+
+ class << self
+ # Default messages to use for validation errors in ORM integrations
+ #
+ # source://state_machines//lib/state_machines/machine.rb#451
+ def default_messages; end
+
+ # Default messages to use for validation errors in ORM integrations
+ #
+ # source://state_machines//lib/state_machines/machine.rb#451
+ def default_messages=(_arg0); end
+
+ # source://state_machines//lib/state_machines/machine.rb#446
+ def draw(*_arg0); end
+
+ # Attempts to find or create a state machine for the given class. For
+ # example,
+ #
+ # StateMachines::Machine.find_or_create(Vehicle)
+ # StateMachines::Machine.find_or_create(Vehicle, :initial => :parked)
+ # StateMachines::Machine.find_or_create(Vehicle, :status)
+ # StateMachines::Machine.find_or_create(Vehicle, :status, :initial => :parked)
+ #
+ # If a machine of the given name already exists in one of the class's
+ # superclasses, then a copy of that machine will be created and stored
+ # in the new owner class (the original will remain unchanged).
+ #
+ # source://state_machines//lib/state_machines/machine.rb#417
+ def find_or_create(owner_class, *args, &block); end
+
+ # Returns the value of attribute ignore_method_conflicts.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#452
+ def ignore_method_conflicts; end
+
+ # Sets the attribute ignore_method_conflicts
+ #
+ # @param value the value to set the attribute ignore_method_conflicts to.
+ #
+ # source://state_machines//lib/state_machines/machine.rb#452
+ def ignore_method_conflicts=(_arg0); end
+ end
+end
+
+# Represents a collection of state machines for a class
+#
+# source://state_machines//lib/state_machines/machine_collection.rb#3
+class StateMachines::MachineCollection < ::Hash
+ # Runs one or more events in parallel on the given object. See
+ # StateMachines::InstanceMethods#fire_events for more information.
+ #
+ # source://state_machines//lib/state_machines/machine_collection.rb#44
+ def fire_events(object, *events); end
+
+ # Initializes the state of each machine in the given object. This can allow
+ # states to be initialized in two groups: static and dynamic. For example:
+ #
+ # machines.initialize_states(object) do
+ # # After static state initialization, before dynamic state initialization
+ # end
+ #
+ # If no block is provided, then all states will still be initialized.
+ #
+ # Valid configuration options:
+ # * :static - Whether to initialize static states. Unless set to
+ # false, the state will be initialized regardless of its current value.
+ # Default is true.
+ # * :dynamic - Whether to initialize dynamic states. If set to
+ # :force, the state will be initialized regardless of its current value.
+ # Default is true.
+ # * :to - A hash to write the initialized state to instead of
+ # writing to the object. Default is to write directly to the object.
+ #
+ # source://state_machines//lib/state_machines/machine_collection.rb#22
+ def initialize_states(object, options = T.unsafe(nil), attributes = T.unsafe(nil)); end
+
+ # Builds the collection of transitions for all event attributes defined on
+ # the given object. This will only include events whose machine actions
+ # match the one specified.
+ #
+ # These should only be fired as a result of the action being run.
+ #
+ # source://state_machines//lib/state_machines/machine_collection.rb#76
+ def transitions(object, action, options = T.unsafe(nil)); end
+
+ protected
+
+ # source://state_machines//lib/state_machines/machine_collection.rb#86
+ def resolve_use_transactions; end
+end
+
+# source://state_machines//lib/state_machines/macro_methods.rb#5
+module StateMachines::MacroMethods
+ # Creates a new state machine with the given name. The default name, if not
+ # specified, is :state.
+ #
+ # Configuration options:
+ # * :attribute - The name of the attribute to store the state value
+ # in. By default, this is the same as the name of the machine.
+ # * :initial - The initial state of the attribute. This can be a
+ # static state or a lambda block which will be evaluated at runtime
+ # (e.g. lambda {|vehicle| vehicle.speed == 0 ? :parked : :idling}).
+ # Default is nil.
+ # * :initialize - Whether to automatically initialize the attribute
+ # by hooking into #initialize on the owner class. Default is true.
+ # * :action - The instance method to invoke when an object
+ # transitions. Default is nil unless otherwise specified by the
+ # configured integration.
+ # * :namespace - The name to use for namespacing all generated
+ # state / event instance methods (e.g. "heater" would generate
+ # :turn_on_heater and :turn_off_heater for the :turn_on/:turn_off events).
+ # Default is nil.
+ # * :integration - The name of the integration to use for adding
+ # library-specific behavior to the machine. Built-in integrations
+ # include :active_model, :active_record, :data_mapper, :mongo_mapper, and
+ # :sequel. By default, this is determined automatically.
+ #
+ # Configuration options relevant to ORM integrations:
+ # * :plural - The pluralized version of the name. By default, this
+ # will attempt to call +pluralize+ on the name. If this method is not
+ # available, an "s" is appended. This is used for generating scopes.
+ # * :messages - The error messages to use when invalidating
+ # objects due to failed transitions. Messages include:
+ # * :invalid
+ # * :invalid_event
+ # * :invalid_transition
+ # * :use_transactions - Whether transactions should be used when
+ # firing events. Default is true unless otherwise specified by the
+ # configured integration.
+ #
+ # This also expects a block which will be used to actually configure the
+ # states, events and transitions for the state machine. *Note* that this
+ # block will be executed within the context of the state machine. As a
+ # result, you will not be able to access any class methods unless you refer
+ # to them directly (i.e. specifying the class name).
+ #
+ # For examples on the types of state machine configurations and blocks, see
+ # the section below.
+ #
+ # == Examples
+ #
+ # With the default name/attribute and no configuration:
+ #
+ # class Vehicle
+ # state_machine do
+ # event :park do
+ # ...
+ # end
+ # end
+ # end
+ #
+ # The above example will define a state machine named "state" that will
+ # store the value in the +state+ attribute. Every vehicle will start
+ # without an initial state.
+ #
+ # With a custom name / attribute:
+ #
+ # class Vehicle
+ # state_machine :status, :attribute => :status_value do
+ # ...
+ # end
+ # end
+ #
+ # With a static initial state:
+ #
+ # class Vehicle
+ # state_machine :status, :initial => :parked do
+ # ...
+ # end
+ # end
+ #
+ # With a dynamic initial state:
+ #
+ # class Vehicle
+ # state_machine :status, :initial => lambda {|vehicle| vehicle.speed == 0 ? :parked : :idling} do
+ # ...
+ # end
+ # end
+ #
+ # == Class Methods
+ #
+ # The following class methods will be automatically generated by the
+ # state machine based on the *name* of the machine. Any existing methods
+ # will not be overwritten.
+ # * human_state_name(state) - Gets the humanized value for the
+ # given state. This may be generated by internationalization libraries if
+ # supported by the integration.
+ # * human_state_event_name(event) - Gets the humanized value for
+ # the given event. This may be generated by internationalization
+ # libraries if supported by the integration.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # event :shift_up do
+ # transition :idling => :first_gear
+ # end
+ # end
+ # end
+ #
+ # Vehicle.human_state_name(:parked) # => "parked"
+ # Vehicle.human_state_name(:first_gear) # => "first gear"
+ # Vehicle.human_state_event_name(:park) # => "park"
+ # Vehicle.human_state_event_name(:shift_up) # => "shift up"
+ #
+ # == Instance Methods
+ #
+ # The following instance methods will be automatically generated by the
+ # state machine based on the *name* of the machine. Any existing methods
+ # will not be overwritten.
+ # * state - Gets the current value for the attribute
+ # * state=(value) - Sets the current value for the attribute
+ # * state?(name) - Checks the given state name against the current
+ # state. If the name is not a known state, then an ArgumentError is raised.
+ # * state_name - Gets the name of the state for the current value
+ # * human_state_name - Gets the human-readable name of the state
+ # for the current value
+ # * state_events(requirements = {}) - Gets the list of events that
+ # can be fired on the current object's state (uses the *unqualified* event
+ # names)
+ # * state_transitions(requirements = {}) - Gets the list of
+ # transitions that can be made on the current object's state
+ # * state_paths(requirements = {}) - Gets the list of sequences of
+ # transitions that can be run from the current object's state
+ # * fire_state_event(name, *args) - Fires an arbitrary event with
+ # the given argument list. This is essentially the same as calling the
+ # actual event method itself.
+ #
+ # The state_events, state_transitions, and state_paths
+ # helpers all take an optional set of requirements for determining what's
+ # available for the current object. These requirements include:
+ # * :from - One or more states to transition from. If none are
+ # specified, then this will be the object's current state.
+ # * :to - One or more states to transition to. If none are
+ # specified, then this will match any to state.
+ # * :on - One or more events to transition on. If none are
+ # specified, then this will match any event.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one. Default is true.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ #
+ # event :park do
+ # transition :idling => :parked
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # vehicle.state # => "parked"
+ # vehicle.state_name # => :parked
+ # vehicle.human_state_name # => "parked"
+ # vehicle.state?(:parked) # => true
+ #
+ # # Changing state
+ # vehicle.state = 'idling'
+ # vehicle.state # => "idling"
+ # vehicle.state_name # => :idling
+ # vehicle.state?(:parked) # => false
+ #
+ # # Getting current event / transition availability
+ # vehicle.state_events # => [:park]
+ # vehicle.park # => true
+ # vehicle.state_events # => [:ignite]
+ # vehicle.state_events(:from => :idling) # => [:park]
+ # vehicle.state_events(:to => :parked) # => []
+ #
+ # vehicle.state_transitions # => [#]
+ # vehicle.ignite # => true
+ # vehicle.state_transitions # => [#]
+ #
+ # vehicle.state_transitions(:on => :ignite) # => []
+ #
+ # # Getting current path availability
+ # vehicle.state_paths # => [
+ # # [#,
+ # # #]
+ # # ]
+ # vehicle.state_paths(:guard => false) # =>
+ # # [#,
+ # # #]
+ # # ]
+ #
+ # # Fire arbitrary events
+ # vehicle.fire_state_event(:park) # => true
+ #
+ # == Attribute initialization
+ #
+ # For most classes, the initial values for state machine attributes are
+ # automatically assigned when a new object is created. However, this
+ # behavior will *not* work if the class defines an +initialize+ method
+ # without properly calling +super+.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ #
+ # In the above example, no +initialize+ method is defined. As a result,
+ # the default behavior of initializing the state machine attributes is used.
+ #
+ # In the following example, a custom +initialize+ method is defined:
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # ...
+ # end
+ #
+ # def initialize
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => nil
+ #
+ # Since the +initialize+ method is defined, the state machine attributes
+ # never get initialized. In order to ensure that all initialization hooks
+ # are called, the custom method *must* call +super+ without any arguments
+ # like so:
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # ...
+ # end
+ #
+ # def initialize(attributes = {})
+ # ...
+ # super()
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ #
+ # Because of the way the inclusion of modules works in Ruby, calling
+ # super() will not only call the superclass's +initialize+, but
+ # also +initialize+ on all included modules. This allows the original state
+ # machine hook to get called properly.
+ #
+ # If you want to avoid calling the superclass's constructor, but still want
+ # to initialize the state machine attributes:
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # ...
+ # end
+ #
+ # def initialize(attributes = {})
+ # ...
+ # initialize_state_machines
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ #
+ # You may also need to call the +initialize_state_machines+ helper manually
+ # in cases where you want to change how static / dynamic initial states get
+ # set. For example, the following example forces the initialization of
+ # static states regardless of their current value:
+ #
+ # class Vehicle
+ # state_machine :state, :initial => :parked do
+ # state nil, :idling
+ # ...
+ # end
+ #
+ # def initialize(attributes = {})
+ # @state = 'idling'
+ # initialize_state_machines(:static => :force) do
+ # ...
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => "parked"
+ #
+ # The above example is also noteworthy because it demonstrates how to avoid
+ # initialization issues when +nil+ is a valid state. Without passing in
+ # :static => :force, state_machine would never have initialized
+ # the state because +nil+ (the default attribute value) would have been
+ # interpreted as a valid current state. As a result, state_machine would
+ # have simply skipped initialization.
+ #
+ # == States
+ #
+ # All of the valid states for the machine are automatically tracked based
+ # on the events, transitions, and callbacks defined for the machine. If
+ # there are additional states that are never referenced, these should be
+ # explicitly added using the StateMachines::Machine#state or
+ # StateMachines::Machine#other_states helpers.
+ #
+ # When a new state is defined, a predicate method for that state is
+ # generated on the class. For example,
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition all => :idling
+ # end
+ # end
+ # end
+ #
+ # ...will generate the following instance methods (assuming they're not
+ # already defined in the class):
+ # * parked?
+ # * idling?
+ #
+ # Each predicate method will return true if it matches the object's
+ # current state. Otherwise, it will return false.
+ #
+ # == Attribute access
+ #
+ # The actual value for a state is stored in the attribute configured for the
+ # state machine. In most cases, this is the same as the name of the state
+ # machine. For example:
+ #
+ # class Vehicle
+ # attr_accessor :state
+ #
+ # state_machine :state, :initial => :parked do
+ # ...
+ # state :parked, :value => 0
+ # start :idling, :value => 1
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # vehicle.state # => 0
+ # vehicle.parked? # => true
+ # vehicle.state = 1
+ # vehicle.idling? # => true
+ #
+ # The most important thing to note from the example above is what it means
+ # to read from and write to the state machine's attribute. In particular,
+ # state_machine treats the attribute (+state+ in this case) like a basic
+ # attr_accessor that's been defined on the class. There are no special
+ # behaviors added, such as allowing the attribute to be written to based on
+ # the name of a state in the machine. This is the case for a few reasons:
+ # * Setting the attribute directly is an edge case that is meant to only be
+ # used when you want to skip state_machine altogether. This means that
+ # state_machine shouldn't have any effect on the attribute accessor
+ # methods. If you want to change the state, you should be using one of
+ # the events defined in the state machine.
+ # * Many ORMs provide custom behavior for the attribute reader / writer - it
+ # may even be defined by your own framework / method implementation just
+ # the example above showed. In order to avoid having to worry about the
+ # different ways an attribute can get written, state_machine just makes
+ # sure that the configured value for a state is always used when writing
+ # to the attribute.
+ #
+ # If you were interested in accessing the name of a state (instead of its
+ # actual value through the attribute), you could do the following:
+ #
+ # vehicle.state_name # => :idling
+ #
+ # == Events and Transitions
+ #
+ # Events defined on the machine are the interface to transitioning states
+ # for an object. Events can be fired either directly (through the method
+ # generated for the event) or indirectly (through attributes defined on
+ # the machine).
+ #
+ # For example,
+ #
+ # class Vehicle
+ # include DataMapper::Resource
+ # property :id, Serial
+ #
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ #
+ # state_machine :alarm_state, :initial => :active do
+ # event :disable do
+ # transition all => :off
+ # end
+ # end
+ # end
+ #
+ # # Fire +ignite+ event directly
+ # vehicle = Vehicle.create # => #
+ # vehicle.ignite # => true
+ # vehicle.state # => "idling"
+ # vehicle.alarm_state # => "active"
+ #
+ # # Fire +disable+ event automatically
+ # vehicle.alarm_state_event = 'disable'
+ # vehicle.save # => true
+ # vehicle.alarm_state # => "off"
+ #
+ # In the above example, the +state+ attribute is transitioned using the
+ # +ignite+ action that's generated from the state machine. On the other
+ # hand, the +alarm_state+ attribute is transitioned using the +alarm_state_event+
+ # attribute that automatically gets fired when the machine's action (+save+)
+ # is invoked.
+ #
+ # For more information about how to configure an event and its associated
+ # transitions, see StateMachines::Machine#event.
+ #
+ # == Defining callbacks
+ #
+ # Within the +state_machine+ block, you can also define callbacks for
+ # transitions. For more information about defining these callbacks,
+ # see StateMachines::Machine#before_transition, StateMachines::Machine#after_transition,
+ # and StateMachines::Machine#around_transition, and StateMachines::Machine#after_failure.
+ #
+ # == Namespaces
+ #
+ # When a namespace is configured for a state machine, the name provided
+ # will be used in generating the instance methods for interacting with
+ # states/events in the machine. This is particularly useful when a class
+ # has multiple state machines and it would be difficult to differentiate
+ # between the various states / events.
+ #
+ # For example,
+ #
+ # class Vehicle
+ # state_machine :heater_state, :initial => :off, :namespace => 'heater' do
+ # event :turn_on do
+ # transition all => :on
+ # end
+ #
+ # event :turn_off do
+ # transition all => :off
+ # end
+ # end
+ #
+ # state_machine :alarm_state, :initial => :active, :namespace => 'alarm' do
+ # event :turn_on do
+ # transition all => :active
+ # end
+ #
+ # event :turn_off do
+ # transition all => :off
+ # end
+ # end
+ # end
+ #
+ # The above class defines two state machines: +heater_state+ and +alarm_state+.
+ # For the +heater_state+ machine, the following methods are generated since
+ # it's namespaced by "heater":
+ # * can_turn_on_heater?
+ # * turn_on_heater
+ # * ...
+ # * can_turn_off_heater?
+ # * turn_off_heater
+ # * ..
+ # * heater_off?
+ # * heater_on?
+ #
+ # As shown, each method is unique to the state machine so that the states
+ # and events don't conflict. The same goes for the +alarm_state+ machine:
+ # * can_turn_on_alarm?
+ # * turn_on_alarm
+ # * ...
+ # * can_turn_off_alarm?
+ # * turn_off_alarm
+ # * ..
+ # * alarm_active?
+ # * alarm_off?
+ #
+ # == Scopes
+ #
+ # For integrations that support it, a group of default scope filters will
+ # be automatically created for assisting in finding objects that have the
+ # attribute set to one of a given set of states.
+ #
+ # For example,
+ #
+ # Vehicle.with_state(:parked) # => All vehicles where the state is parked
+ # Vehicle.with_states(:parked, :idling) # => All vehicles where the state is either parked or idling
+ #
+ # Vehicle.without_state(:parked) # => All vehicles where the state is *not* parked
+ # Vehicle.without_states(:parked, :idling) # => All vehicles where the state is *not* parked or idling
+ #
+ # *Note* that if class methods already exist with those names (i.e.
+ # :with_state, :with_states, :without_state, or :without_states), then a
+ # scope will not be defined for that name.
+ #
+ # See StateMachines::Machine for more information about using integrations
+ # and the individual integration docs for information about the actual
+ # scopes that are generated.
+ #
+ # source://state_machines//lib/state_machines/macro_methods.rb#516
+ def state_machine(*args, &block); end
+end
+
+# Provides a general strategy pattern for determining whether a match is found
+# for a value. The algorithm that actually determines the match depends on
+# the matcher in use.
+#
+# source://state_machines//lib/state_machines/matcher.rb#5
+class StateMachines::Matcher
+ # Creates a new matcher for querying against the given set of values
+ #
+ # @return [Matcher] a new instance of Matcher
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#10
+ def initialize(values = T.unsafe(nil)); end
+
+ # Generates a subset of values that exists in both the set of values being
+ # filtered and the values configured for the matcher
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#16
+ def filter(values); end
+
+ # The list of values against which queries are matched
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#7
+ def values; end
+end
+
+# Provides a set of helper methods for generating matchers
+#
+# source://state_machines//lib/state_machines/matcher_helpers.rb#3
+module StateMachines::MatcherHelpers
+ # Represents a state that matches all known states in a machine.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition any => :parked, :do => lambda {...}
+ # before_transition all - :parked => all - :idling, :do => lambda {}
+ #
+ # event :park
+ # transition all => :parked
+ # end
+ #
+ # event :crash
+ # transition all - :parked => :stalled
+ # end
+ # end
+ # end
+ #
+ # In the above example, +all+ will match the following states since they
+ # are known:
+ # * +parked+
+ # * +stalled+
+ # * +idling+
+ #
+ # source://state_machines//lib/state_machines/matcher_helpers.rb#28
+ def all; end
+
+ # Represents a state that matches all known states in a machine.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine do
+ # before_transition any => :parked, :do => lambda {...}
+ # before_transition all - :parked => all - :idling, :do => lambda {}
+ #
+ # event :park
+ # transition all => :parked
+ # end
+ #
+ # event :crash
+ # transition all - :parked => :stalled
+ # end
+ # end
+ # end
+ #
+ # In the above example, +all+ will match the following states since they
+ # are known:
+ # * +parked+
+ # * +stalled+
+ # * +idling+
+ #
+ # source://state_machines//lib/state_machines/matcher_helpers.rb#28
+ def any; end
+
+ # Represents a state that matches the original +from+ state. This is useful
+ # for defining transitions which are loopbacks.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine do
+ # event :ignite
+ # transition [:idling, :first_gear] => same
+ # end
+ # end
+ # end
+ #
+ # In the above example, +same+ will match whichever the from state is. In
+ # the case of the +ignite+ event, it is essential the same as the following:
+ #
+ # transition :idling => :idling, :first_gear => :first_gear
+ #
+ # source://state_machines//lib/state_machines/matcher_helpers.rb#50
+ def same; end
+end
+
+# Represents a collection of nodes in a state machine, be it events or states.
+# Nodes will not differentiate between the String and Symbol versions of the
+# values being indexed.
+#
+# source://state_machines//lib/state_machines/node_collection.rb#5
+class StateMachines::NodeCollection
+ include ::Enumerable
+
+ # Creates a new collection of nodes for the given state machine. By default,
+ # the collection is empty.
+ #
+ # Configuration options:
+ # * :index - One or more attributes to automatically generate
+ # hashed indices for in order to perform quick lookups. Default is to
+ # index by the :name attribute
+ #
+ # @return [NodeCollection] a new instance of NodeCollection
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#18
+ def initialize(machine, options = T.unsafe(nil)); end
+
+ # Adds a new node to the collection. By doing so, this will also add it to
+ # the configured indices. This will also evaluate any existings contexts
+ # that match the new node.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#85
+ def <<(node); end
+
+ # Gets the node indexed by the given key. By default, this will look up the
+ # key in the first index configured for the collection. A custom index can
+ # be specified like so:
+ #
+ # collection['parked', :value]
+ #
+ # The above will look up the "parked" key in a hash indexed by each node's
+ # +value+ attribute.
+ #
+ # If the key cannot be found, then nil will be returned.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#142
+ def [](key, index_name = T.unsafe(nil)); end
+
+ # Gets the node at the given index.
+ #
+ # states = StateMachines::NodeCollection.new
+ # states << StateMachines::State.new(machine, :parked)
+ # states << StateMachines::State.new(machine, :idling)
+ #
+ # states.at(0).name # => :parked
+ # states.at(1).name # => :idling
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#128
+ def at(index); end
+
+ # Appends a group of nodes to the collection
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#93
+ def concat(nodes); end
+
+ # Tracks a context that should be evaluated for any nodes that get added
+ # which match the given set of nodes. Matchers can be used so that the
+ # context can get added once and evaluated after multiple adds.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#72
+ def context(nodes, &block); end
+
+ # Calls the block once for each element in self, passing that element as a
+ # parameter.
+ #
+ # states = StateMachines::NodeCollection.new
+ # states << StateMachines::State.new(machine, :parked)
+ # states << StateMachines::State.new(machine, :idling)
+ # states.each {|state| puts state.name, ' -- '}
+ #
+ # ...produces:
+ #
+ # parked -- idling --
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#115
+ def each; end
+
+ # Gets the node indexed by the given key. By default, this will look up the
+ # key in the first index configured for the collection. A custom index can
+ # be specified like so:
+ #
+ # collection['parked', :value]
+ #
+ # The above will look up the "parked" key in a hash indexed by each node's
+ # +value+ attribute.
+ #
+ # If the key cannot be found, then an IndexError exception will be raised:
+ #
+ # collection['invalid', :value] # => IndexError: "invalid" is an invalid value
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#161
+ def fetch(key, index_name = T.unsafe(nil)); end
+
+ # Gets the set of unique keys for the given index
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#65
+ def keys(index_name = T.unsafe(nil)); end
+
+ # Gets the number of nodes in this collection
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#60
+ def length; end
+
+ # The machine associated with the nodes
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#9
+ def machine; end
+
+ # Changes the current machine associated with the collection. In turn, this
+ # will change the state machine associated with each node in the collection.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#54
+ def machine=(new_machine); end
+
+ # Updates the indexed keys for the given node. If the node's attribute
+ # has changed since it was added to the collection, the old indexed keys
+ # will be replaced with the updated ones.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#100
+ def update(node); end
+
+ protected
+
+ # Adds the given key / node combination to an index, including the string
+ # and symbol versions of the index
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#182
+ def add_to_index(name, key, node); end
+
+ # Evaluates the given context for a particular node. This will only
+ # evaluate the context if the node matches.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#217
+ def eval_context(context, node); end
+
+ # Gets the given index. If the index does not exist, then an ArgumentError
+ # is raised.
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#169
+ def index(name); end
+
+ # Removes the given key from an index, including the string and symbol
+ # versions of the index
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#190
+ def remove_from_index(name, key); end
+
+ # Determines whether the given value can be converted to a symbol
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#211
+ def to_sym?(value); end
+
+ # Updates the node for the given index, including the string and symbol
+ # versions of the index
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#198
+ def update_index(name, node); end
+
+ # Gets the value for the given attribute on the node
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#176
+ def value(node, attribute); end
+
+ private
+
+ # Creates a copy of this collection such that modifications don't affect
+ # the original collection
+ #
+ # source://state_machines//lib/state_machines/node_collection.rb#37
+ def initialize_copy(orig); end
+end
+
+# A path represents a sequence of transitions that can be run for a particular
+# object. Paths can walk to new transitions, revealing all of the possible
+# branches that can be encountered in the object's state machine.
+#
+# source://state_machines//lib/state_machines/path.rb#5
+class StateMachines::Path < ::Array
+ # Creates a new transition path for the given object. Initially this is an
+ # empty path. In order to start walking the path, it must be populated with
+ # an initial transition.
+ #
+ # Configuration options:
+ # * :target - The target state to end the path on
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one
+ #
+ # @return [Path] a new instance of Path
+ #
+ # source://state_machines//lib/state_machines/path.rb#22
+ def initialize(object, machine, options = T.unsafe(nil)); end
+
+ # Determines whether or not this path has completed. A path is considered
+ # complete when one of the following conditions is met:
+ # * The last transition in the path ends on the target state
+ # * There are no more transitions remaining to walk and there is no target
+ # state
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/path.rb#85
+ def complete?; end
+
+ # Lists all of the events that can be fired through this path.
+ #
+ # For example,
+ #
+ # path.events # => [:park, :ignite, :shift_up, ...]
+ #
+ # source://state_machines//lib/state_machines/path.rb#70
+ def events; end
+
+ # The initial state name for this path
+ #
+ # source://state_machines//lib/state_machines/path.rb#37
+ def from_name; end
+
+ # Lists all of the from states that can be reached through this path.
+ #
+ # For example,
+ #
+ # path.to_states # => [:parked, :idling, :first_gear, ...]
+ #
+ # source://state_machines//lib/state_machines/path.rb#46
+ def from_states; end
+
+ # The state machine this path is walking
+ #
+ # source://state_machines//lib/state_machines/path.rb#12
+ def machine; end
+
+ # The object whose state machine is being walked
+ #
+ # source://state_machines//lib/state_machines/path.rb#9
+ def object; end
+
+ # The end state name for this path. If a target state was specified for
+ # the path, then that will be returned if the path is complete.
+ #
+ # source://state_machines//lib/state_machines/path.rb#52
+ def to_name; end
+
+ # Lists all of the to states that can be reached through this path.
+ #
+ # For example,
+ #
+ # path.to_states # => [:parked, :idling, :first_gear, ...]
+ #
+ # source://state_machines//lib/state_machines/path.rb#61
+ def to_states; end
+
+ # Walks down the next transitions at the end of this path. This will only
+ # walk down paths that are considered valid.
+ #
+ # source://state_machines//lib/state_machines/path.rb#76
+ def walk; end
+
+ private
+
+ # Determines whether it's possible to walk to the given transition from
+ # the current path. A transition can be walked to if:
+ # * It has not been recently walked and
+ # * If a target is specified, it has not been walked to twice yet
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/path.rb#111
+ def can_walk_to?(transition); end
+
+ # source://state_machines//lib/state_machines/path.rb#31
+ def initialize_copy(orig); end
+
+ # Determines whether the given transition has been recently walked down in
+ # this path. If a target is configured for this path, then this will only
+ # look at transitions walked down since the target was last reached.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/path.rb#99
+ def recently_walked?(transition); end
+
+ # Calculates the number of times the given state has been walked to
+ #
+ # source://state_machines//lib/state_machines/path.rb#92
+ def times_walked_to(state); end
+
+ # Get the next set of transitions that can be walked to starting from the
+ # end of this path
+ #
+ # source://state_machines//lib/state_machines/path.rb#117
+ def transitions; end
+end
+
+# Represents a collection of paths that are generated based on a set of
+# requirements regarding what states to start and end on
+#
+# source://state_machines//lib/state_machines/path_collection.rb#4
+class StateMachines::PathCollection < ::Array
+ # Creates a new collection of paths with the given requirements.
+ #
+ # Configuration options:
+ # * :from - The initial state to start from
+ # * :to - The target end state
+ # * :deep - Whether to enable deep searches for the target state.
+ # * :guard - Whether to guard transitions with the if/unless
+ # conditionals defined for each one
+ #
+ # @return [PathCollection] a new instance of PathCollection
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#26
+ def initialize(object, machine, options = T.unsafe(nil)); end
+
+ # Lists all of the events that can be fired through the paths in this
+ # collection.
+ #
+ # For example,
+ #
+ # paths.events # => [:park, :ignite, :shift_up, ...]
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#66
+ def events; end
+
+ # The initial state to start each path from
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#13
+ def from_name; end
+
+ # Lists all of the states that can be transitioned from through the paths in
+ # this collection.
+ #
+ # For example,
+ #
+ # paths.from_states # => [:parked, :idling, :first_gear, ...]
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#46
+ def from_states; end
+
+ # The state machine these path are walking
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#10
+ def machine; end
+
+ # The object whose state machine is being walked
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#7
+ def object; end
+
+ # The target state for each path
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#16
+ def to_name; end
+
+ # Lists all of the states that can be transitioned to through the paths in
+ # this collection.
+ #
+ # For example,
+ #
+ # paths.to_states # => [:idling, :first_gear, :second_gear, ...]
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#56
+ def to_states; end
+
+ private
+
+ # Gets the initial set of paths to walk
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#73
+ def initial_paths; end
+
+ # Walks down the given path. Each new path that matches the configured
+ # requirements will be added to this collection.
+ #
+ # source://state_machines//lib/state_machines/path_collection.rb#83
+ def walk(path); end
+end
+
+# A state defines a value that an attribute can be in after being transitioned
+# 0 or more times. States can represent a value of any type in Ruby, though
+# the most common (and default) type is String.
+#
+# In addition to defining the machine's value, a state can also define a
+# behavioral context for an object when that object is in the state. See
+# StateMachines::Machine#state for more information about how state-driven
+# behavior can be utilized.
+#
+# source://state_machines//lib/state_machines/state.rb#10
+class StateMachines::State
+ # Creates a new state within the context of the given machine.
+ #
+ # Configuration options:
+ # * :initial - Whether this state is the beginning state for the
+ # machine. Default is false.
+ # * :value - The value to store when an object transitions to this
+ # state. Default is the name (stringified).
+ # * :cache - If a dynamic value (via a lambda block) is being used,
+ # then setting this to true will cache the evaluated result
+ # * :if - Determines whether a value matches this state
+ # (e.g. :value => lambda {Time.now}, :if => lambda {|state| !state.nil?}).
+ # By default, the configured value is matched.
+ # * :human_name - The human-readable version of this state's name
+ #
+ # @return [State] a new instance of State
+ #
+ # source://state_machines//lib/state_machines/state.rb#53
+ def initialize(machine, name, options = T.unsafe(nil)); end
+
+ # Whether this state's value should be cached after being evaluated
+ #
+ # source://state_machines//lib/state_machines/state.rb#30
+ def cache; end
+
+ # Whether this state's value should be cached after being evaluated
+ #
+ # source://state_machines//lib/state_machines/state.rb#30
+ def cache=(_arg0); end
+
+ # Calls a method defined in this state's context on the given object. All
+ # arguments and any block will be passed into the method defined.
+ #
+ # If the method has never been defined for this state, then a NoMethodError
+ # will be raised.
+ #
+ # source://state_machines//lib/state_machines/state.rb#219
+ def call(object, method, *args, &block); end
+
+ # Defines a context for the state which will be enabled on instances of
+ # the owner class when the machine is in this state.
+ #
+ # This can be called multiple times. Each time a new context is created,
+ # a new module will be included in the owner class.
+ #
+ # source://state_machines//lib/state_machines/state.rb#181
+ def context(&block); end
+
+ # The list of methods that have been defined in this state's context
+ #
+ # source://state_machines//lib/state_machines/state.rb#208
+ def context_methods; end
+
+ # Generates a human-readable description of this state's name / value:
+ #
+ # For example,
+ #
+ # State.new(machine, :parked).description # => "parked"
+ # State.new(machine, :parked, :value => :parked).description # => "parked"
+ # State.new(machine, :parked, :value => nil).description # => "parked (nil)"
+ # State.new(machine, :parked, :value => 1).description # => "parked (1)"
+ # State.new(machine, :parked, :value => lambda {Time.now}).description # => "parked (*)
+ #
+ # Configuration options:
+ # * :human_name - Whether to use this state's human name in the
+ # description or just the internal name
+ #
+ # source://state_machines//lib/state_machines/state.rb#127
+ def description(options = T.unsafe(nil)); end
+
+ # source://state_machines//lib/state_machines/state.rb#242
+ def draw(graph, options = T.unsafe(nil)); end
+
+ # Determines whether there are any states that can be transitioned to from
+ # this state. If there are none, then this state is considered *final*.
+ # Any objects in a final state will remain so forever given the current
+ # machine's definition.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/state.rb#98
+ def final?; end
+
+ # Transforms the state name into a more human-readable format, such as
+ # "first gear" instead of "first_gear"
+ #
+ # source://state_machines//lib/state_machines/state.rb#110
+ def human_name(klass = T.unsafe(nil)); end
+
+ # The human-readable name for the state
+ #
+ # source://state_machines//lib/state_machines/state.rb#23
+ def human_name=(_arg0); end
+
+ # Whether or not this state is the initial state to use for new objects
+ #
+ # source://state_machines//lib/state_machines/state.rb#33
+ def initial; end
+
+ # Whether or not this state is the initial state to use for new objects
+ #
+ # source://state_machines//lib/state_machines/state.rb#33
+ def initial=(_arg0); end
+
+ # Whether or not this state is the initial state to use for new objects
+ #
+ # source://state_machines//lib/state_machines/state.rb#33
+ def initial?; end
+
+ # Generates a nicely formatted description of this state's contents.
+ #
+ # For example,
+ #
+ # state = StateMachines::State.new(machine, :parked, :value => 1, :initial => true)
+ # state # => #
+ #
+ # source://state_machines//lib/state_machines/state.rb#252
+ def inspect; end
+
+ # The state machine for which this state is defined
+ #
+ # source://state_machines//lib/state_machines/state.rb#13
+ def machine; end
+
+ # source://state_machines//lib/state_machines/state.rb#89
+ def machine=(machine); end
+
+ # A custom lambda block for determining whether a given value matches this
+ # state
+ #
+ # source://state_machines//lib/state_machines/state.rb#38
+ def matcher; end
+
+ # A custom lambda block for determining whether a given value matches this
+ # state
+ #
+ # source://state_machines//lib/state_machines/state.rb#38
+ def matcher=(_arg0); end
+
+ # Determines whether this state matches the given value. If no matcher is
+ # configured, then this will check whether the values are equivalent.
+ # Otherwise, the matcher will determine the result.
+ #
+ # For example,
+ #
+ # # Without a matcher
+ # state = State.new(machine, :parked, :value => 1)
+ # state.matches?(1) # => true
+ # state.matches?(2) # => false
+ #
+ # # With a matcher
+ # state = State.new(machine, :parked, :value => lambda {Time.now}, :if => lambda {|value| !value.nil?})
+ # state.matches?(nil) # => false
+ # state.matches?(Time.now) # => true
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/state.rb#172
+ def matches?(other_value); end
+
+ # The unique identifier for the state used in event and callback definitions
+ #
+ # source://state_machines//lib/state_machines/state.rb#16
+ def name; end
+
+ # The fully-qualified identifier for the state, scoped by the machine's
+ # namespace
+ #
+ # source://state_machines//lib/state_machines/state.rb#20
+ def qualified_name; end
+
+ # The value that represents this state. This will optionally evaluate the
+ # original block if it's a lambda block. Otherwise, the static value is
+ # returned.
+ #
+ # For example,
+ #
+ # State.new(machine, :parked, :value => 1).value # => 1
+ # State.new(machine, :parked, :value => lambda {Time.now}).value # => Tue Jan 01 00:00:00 UTC 2008
+ # State.new(machine, :parked, :value => lambda {Time.now}).value(false) # =>
+ #
+ # source://state_machines//lib/state_machines/state.rb#143
+ def value(eval = T.unsafe(nil)); end
+
+ # The value that is written to a machine's attribute when an object
+ # transitions into this state
+ #
+ # source://state_machines//lib/state_machines/state.rb#27
+ def value=(_arg0); end
+
+ private
+
+ # Adds a predicate method to the owner class so long as a name has
+ # actually been configured for the state
+ #
+ # source://state_machines//lib/state_machines/state.rb#266
+ def add_predicate; end
+
+ # Should the value be cached after it's evaluated for the first time?
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/state.rb#260
+ def cache_value?; end
+
+ # Generates the name of the method containing the actual implementation
+ #
+ # source://state_machines//lib/state_machines/state.rb#274
+ def context_name_for(method); end
+
+ # Creates a copy of this state, excluding the context to prevent conflicts
+ # across different machines.
+ #
+ # source://state_machines//lib/state_machines/state.rb#84
+ def initialize_copy(orig); end
+end
+
+# Represents a collection of states in a state machine
+#
+# source://state_machines//lib/state_machines/state_collection.rb#3
+class StateMachines::StateCollection < ::StateMachines::NodeCollection
+ # @return [StateCollection] a new instance of StateCollection
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#4
+ def initialize(machine); end
+
+ # Gets the order in which states should be displayed based on where they
+ # were first referenced. This will order states in the following priority:
+ #
+ # 1. Initial state
+ # 2. Event transitions (:from, :except_from, :to, :except_to options)
+ # 3. States with behaviors
+ # 4. States referenced via +state+ or +other_states+
+ # 5. States referenced in callbacks
+ #
+ # This order will determine how the GraphViz visualizations are rendered.
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#91
+ def by_priority; end
+
+ # Determines the current state of the given object as configured by this
+ # state machine. This will attempt to find a known state that matches
+ # the value of the attribute on the object.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # other_states :idling
+ # end
+ # end
+ #
+ # states = Vehicle.state_machine.states
+ #
+ # vehicle = Vehicle.new # => #
+ # states.match(vehicle) # => #
+ #
+ # vehicle.state = 'idling'
+ # states.match(vehicle) # => #
+ #
+ # vehicle.state = 'invalid'
+ # states.match(vehicle) # => nil
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#53
+ def match(object); end
+
+ # Determines the current state of the given object as configured by this
+ # state machine. If no state is found, then an ArgumentError will be
+ # raised.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # other_states :idling
+ # end
+ # end
+ #
+ # states = Vehicle.state_machine.states
+ #
+ # vehicle = Vehicle.new # => #
+ # states.match!(vehicle) # => #
+ #
+ # vehicle.state = 'invalid'
+ # states.match!(vehicle) # => ArgumentError: "invalid" is not a known state value
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#77
+ def match!(object); end
+
+ # Determines whether the given object is in a specific state. If the
+ # object's current value doesn't match the state, then this will return
+ # false, otherwise true. If the given state is unknown, then an IndexError
+ # will be raised.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # other_states :idling
+ # end
+ # end
+ #
+ # states = Vehicle.state_machine.states
+ # vehicle = Vehicle.new # => #
+ #
+ # states.matches?(vehicle, :parked) # => true
+ # states.matches?(vehicle, :idling) # => false
+ # states.matches?(vehicle, :invalid) # => IndexError: :invalid is an invalid key for :name index
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#27
+ def matches?(object, name); end
+
+ private
+
+ # Gets the value for the given attribute on the node
+ #
+ # source://state_machines//lib/state_machines/state_collection.rb#107
+ def value(node, attribute); end
+end
+
+# Represents a module which will get evaluated within the context of a state.
+#
+# Class-level methods are proxied to the owner class, injecting a custom
+# :if condition along with method. This assumes that the method has
+# support for a set of configuration options, including :if. This
+# condition will check that the object's state matches this context's state.
+#
+# Instance-level methods are used to define state-driven behavior on the
+# state's owner class.
+#
+# == Examples
+#
+# class Vehicle
+# class << self
+# attr_accessor :validations
+#
+# def validate(options, &block)
+# validations << options
+# end
+# end
+#
+# self.validations = []
+# attr_accessor :state, :simulate
+#
+# def moving?
+# self.class.validations.all? {|validation| validation[:if].call(self)}
+# end
+# end
+#
+# In the above class, a simple set of validation behaviors have been defined.
+# Each validation consists of a configuration like so:
+#
+# Vehicle.validate :unless => :simulate
+# Vehicle.validate :if => lambda {|vehicle| ...}
+#
+# In order to scope validations to a particular state context, the class-level
+# +validate+ method can be invoked like so:
+#
+# machine = StateMachines::Machine.new(Vehicle)
+# context = StateMachines::StateContext.new(machine.state(:first_gear))
+# context.validate(:unless => :simulate)
+#
+# vehicle = Vehicle.new # => #
+# vehicle.moving? # => false
+#
+# vehicle.state = 'first_gear'
+# vehicle.moving? # => true
+#
+# vehicle.simulate = true
+# vehicle.moving? # => false
+#
+# source://state_machines//lib/state_machines/state_context.rb#52
+class StateMachines::StateContext < ::Module
+ include ::StateMachines::EvalHelpers
+
+ # Creates a new context for the given state
+ #
+ # @return [StateContext] a new instance of StateContext
+ #
+ # source://state_machines//lib/state_machines/state_context.rb#63
+ def initialize(state); end
+
+ # The state machine for which this context's state is defined
+ #
+ # source://state_machines//lib/state_machines/state_context.rb#57
+ def machine; end
+
+ # Hooks in condition-merging to methods that don't exist in this module
+ #
+ # source://state_machines//lib/state_machines/state_context.rb#97
+ def method_missing(*args, &block); end
+
+ # The state that must be present in an object for this context to be active
+ #
+ # source://state_machines//lib/state_machines/state_context.rb#60
+ def state; end
+
+ # Creates a new transition that determines what to change the current state
+ # to when an event fires from this state.
+ #
+ # Since this transition is being defined within a state context, you do
+ # *not* need to specify the :from option for the transition. For
+ # example:
+ #
+ # state_machine do
+ # state :parked do
+ # transition :to => :idling, :on => [:ignite, :shift_up] # Transitions to :idling
+ # transition :from => [:idling, :parked], :on => :park, :unless => :seatbelt_on? # Transitions to :parked if seatbelt is off
+ # end
+ # end
+ #
+ # See StateMachines::Machine#transition for a description of the possible
+ # configurations for defining transitions.
+ #
+ # @raise [ArgumentError]
+ #
+ # source://state_machines//lib/state_machines/state_context.rb#88
+ def transition(options); end
+end
+
+# A transition represents a state change for a specific attribute.
+#
+# Transitions consist of:
+# * An event
+# * A starting state
+# * An ending state
+#
+# source://state_machines//lib/state_machines/transition.rb#8
+class StateMachines::Transition
+ # Creates a new, specific transition
+ #
+ # @return [Transition] a new instance of Transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#38
+ def initialize(object, machine, event, from_name, to_name, read_state = T.unsafe(nil)); end
+
+ # Determines equality of transitions by testing whether the object, states,
+ # and event involved in the transition are equal
+ #
+ # source://state_machines//lib/state_machines/transition.rb#264
+ def ==(other); end
+
+ # The action that will be run when this transition is performed
+ #
+ # source://state_machines//lib/state_machines/transition.rb#60
+ def action; end
+
+ # The arguments passed in to the event that triggered the transition
+ # (does not include the +run_action+ boolean argument if specified)
+ #
+ # source://state_machines//lib/state_machines/transition.rb#23
+ def args; end
+
+ # The arguments passed in to the event that triggered the transition
+ # (does not include the +run_action+ boolean argument if specified)
+ #
+ # source://state_machines//lib/state_machines/transition.rb#23
+ def args=(_arg0); end
+
+ # The attribute which this transition's machine is defined for
+ #
+ # source://state_machines//lib/state_machines/transition.rb#55
+ def attribute; end
+
+ # A hash of all the core attributes defined for this transition with their
+ # names as keys and values of the attributes as values.
+ #
+ # == Example
+ #
+ # machine = StateMachine.new(Vehicle)
+ # transition = StateMachines::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling)
+ # transition.attributes # => {:object => #, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'}
+ #
+ # source://state_machines//lib/state_machines/transition.rb#136
+ def attributes; end
+
+ # The event that triggered the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#65
+ def event; end
+
+ # The original state value *before* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#16
+ def from; end
+
+ # The state name *before* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#80
+ def from_name; end
+
+ # The human-readable name of the event that triggered the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#75
+ def human_event; end
+
+ # The human-readable state name *before* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#90
+ def human_from_name; end
+
+ # The new human-readable state name *after* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#105
+ def human_to_name; end
+
+ # Generates a nicely formatted description of this transitions's contents.
+ #
+ # For example,
+ #
+ # transition = StateMachines::Transition.new(object, machine, :ignite, :parked, :idling)
+ # transition # => #
+ #
+ # source://state_machines//lib/state_machines/transition.rb#279
+ def inspect; end
+
+ # Does this transition represent a loopback (i.e. the from and to state
+ # are the same)
+ #
+ # == Example
+ #
+ # machine = StateMachine.new(Vehicle)
+ # StateMachines::Transition.new(Vehicle.new, machine, :park, :parked, :parked).loopback? # => true
+ # StateMachines::Transition.new(Vehicle.new, machine, :park, :idling, :parked).loopback? # => false
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition.rb#117
+ def loopback?; end
+
+ # The state machine for which this transition is defined
+ #
+ # source://state_machines//lib/state_machines/transition.rb#13
+ def machine; end
+
+ # The object being transitioned
+ #
+ # source://state_machines//lib/state_machines/transition.rb#10
+ def object; end
+
+ # Runs the actual transition and any before/after callbacks associated
+ # with the transition. The action associated with the transition/machine
+ # can be skipped by passing in +false+.
+ #
+ # == Examples
+ #
+ # class Vehicle
+ # state_machine :action => :save do
+ # ...
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # transition = StateMachines::Transition.new(vehicle, machine, :ignite, :parked, :idling)
+ # transition.perform # => Runs the +save+ action after setting the state attribute
+ # transition.perform(false) # => Only sets the state attribute
+ # transition.perform(Time.now) # => Passes in additional arguments and runs the +save+ action
+ # transition.perform(Time.now, false) # => Passes in additional arguments and only sets the state attribute
+ #
+ # source://state_machines//lib/state_machines/transition.rb#158
+ def perform(*args); end
+
+ # Transitions the current value of the state to that specified by the
+ # transition. Once the state is persisted, it cannot be persisted again
+ # until this transition is reset.
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new
+ # transition = StateMachines::Transition.new(vehicle, Vehicle.state_machine, :ignite, :parked, :idling)
+ # transition.persist
+ #
+ # vehicle.state # => 'idling'
+ #
+ # source://state_machines//lib/state_machines/transition.rb#219
+ def persist; end
+
+ # The fully-qualified name of the event that triggered the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#70
+ def qualified_event; end
+
+ # The fully-qualified state name *before* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#85
+ def qualified_from_name; end
+
+ # The new fully-qualified state name *after* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#100
+ def qualified_to_name; end
+
+ # Resets any tracking of which callbacks have already been run and whether
+ # the state has already been persisted
+ #
+ # source://state_machines//lib/state_machines/transition.rb#257
+ def reset; end
+
+ # The result of invoking the action associated with the machine
+ #
+ # source://state_machines//lib/state_machines/transition.rb#26
+ def result; end
+
+ # Rolls back changes made to the object's state via this transition. This
+ # will revert the state back to the +from+ value.
+ #
+ # == Example
+ #
+ # class Vehicle
+ # state_machine :initial => :parked do
+ # event :ignite do
+ # transition :parked => :idling
+ # end
+ # end
+ # end
+ #
+ # vehicle = Vehicle.new # => #
+ # transition = StateMachines::Transition.new(vehicle, Vehicle.state_machine, :ignite, :parked, :idling)
+ #
+ # # Persist the new state
+ # vehicle.state # => "parked"
+ # transition.persist
+ # vehicle.state # => "idling"
+ #
+ # # Roll back to the original state
+ # transition.rollback
+ # vehicle.state # => "parked"
+ #
+ # source://state_machines//lib/state_machines/transition.rb#250
+ def rollback; end
+
+ # Runs the before / after callbacks for this transition. If a block is
+ # provided, then it will be executed between the before and after callbacks.
+ #
+ # Configuration options:
+ # * +before+ - Whether to run before callbacks.
+ # * +after+ - Whether to run after callbacks. If false, then any around
+ # callbacks will be paused until called again with +after+ enabled.
+ # Default is true.
+ #
+ # This will return true if all before callbacks gets executed. After
+ # callbacks will not have an effect on the result.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#186
+ def run_callbacks(options = T.unsafe(nil), &block); end
+
+ # The new state value *after* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#19
+ def to; end
+
+ # The new state name *after* the transition
+ #
+ # source://state_machines//lib/state_machines/transition.rb#95
+ def to_name; end
+
+ # Whether the transition is only existing temporarily for the object
+ #
+ # source://state_machines//lib/state_machines/transition.rb#29
+ def transient=(_arg0); end
+
+ # Is this transition existing for a short period only? If this is set, it
+ # indicates that the transition (or the event backing it) should not be
+ # written to the object if it fails.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition.rb#124
+ def transient?; end
+
+ # Runs a block within a transaction for the object being transitioned.
+ # By default, transactions are a no-op unless otherwise defined by the
+ # machine's integration.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#169
+ def within_transaction; end
+
+ private
+
+ # Runs the machine's +after+ callbacks for this transition. Only
+ # callbacks that are configured to match the event, from state, and to
+ # state will be invoked.
+ #
+ # Once the callbacks are run, they cannot be run again until this transition
+ # is reset.
+ #
+ # == Halting
+ #
+ # If any callback throws a :halt exception, it will be caught
+ # and the callback chain will be automatically stopped. However, this
+ # exception will not bubble up to the caller since +after+ callbacks
+ # should never halt the execution of a +perform+.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#390
+ def after; end
+
+ # Runs the machine's +before+ callbacks for this transition. Only
+ # callbacks that are configured to match the event, from state, and to
+ # state will be invoked.
+ #
+ # Once the callbacks are run, they cannot be run again until this transition
+ # is reset.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#345
+ def before(complete = T.unsafe(nil), index = T.unsafe(nil), &block); end
+
+ # Gets a hash of the context defining this unique transition (including
+ # event, from state, and to state).
+ #
+ # == Example
+ #
+ # machine = StateMachine.new(Vehicle)
+ # transition = StateMachines::Transition.new(Vehicle.new, machine, :ignite, :parked, :idling)
+ # transition.context # => {:on => :ignite, :from => :parked, :to => :idling}
+ #
+ # source://state_machines//lib/state_machines/transition.rb#412
+ def context; end
+
+ # Runs a block that may get paused. If the block doesn't pause, then
+ # execution will continue as normal. If the block gets paused, then it
+ # will take care of switching the execution context when it's resumed.
+ #
+ # This will return true if the given block halts for a reason other than
+ # getting paused.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#291
+ def pausable; end
+
+ # Pauses the current callback execution. This should only occur within
+ # around callbacks when the remainder of the callback will be executed at
+ # a later point in time.
+ #
+ # @raise [ArgumentError]
+ #
+ # source://state_machines//lib/state_machines/transition.rb#308
+ def pause; end
+
+ # Resumes the execution of a previously paused callback execution. Once
+ # the paused callbacks complete, the current execution will continue.
+ #
+ # source://state_machines//lib/state_machines/transition.rb#322
+ def resume; end
+
+ class << self
+ # Determines whether the current ruby implementation supports pausing and
+ # resuming transitions
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition.rb#33
+ def pause_supported?; end
+ end
+end
+
+# Represents a collection of transitions in a state machine
+#
+# source://state_machines//lib/state_machines/transition_collection.rb#3
+class StateMachines::TransitionCollection < ::Array
+ # Creates a new collection of transitions that can be run in parallel. Each
+ # transition *must* be for a different attribute.
+ #
+ # Configuration options:
+ # * :actions - Whether to run the action configured for each transition
+ # * :after - Whether to run after callbacks
+ # * :transaction - Whether to wrap transitions within a transaction
+ #
+ # @return [TransitionCollection] a new instance of TransitionCollection
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#21
+ def initialize(transitions = T.unsafe(nil), options = T.unsafe(nil)); end
+
+ # Runs each of the collection's transitions in parallel.
+ #
+ # All transitions will run through the following steps:
+ # 1. Before callbacks
+ # 2. Persist state
+ # 3. Invoke action
+ # 4. After callbacks (if configured)
+ # 5. Rollback (if action is unsuccessful)
+ #
+ # If a block is passed to this method, that block will be called instead
+ # of invoking each transition's action.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#49
+ def perform(&block); end
+
+ # Whether to skip running the action for each transition's machine
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#6
+ def skip_actions; end
+
+ # Whether to skip running the after callbacks
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#9
+ def skip_after; end
+
+ # Whether transitions should wrapped around a transaction block
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#12
+ def use_transactions; end
+
+ protected
+
+ # source://state_machines//lib/state_machines/transition_collection.rb#77
+ def results; end
+
+ private
+
+ # Gets the list of actions to run. If configured to skip actions, then
+ # this will return an empty collection.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#103
+ def actions; end
+
+ # Wraps the given block with a rescue handler so that any exceptions that
+ # occur will automatically result in the transition rolling back any changes
+ # that were made to the object involved.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#169
+ def catch_exceptions; end
+
+ # Gets the object being transitioned
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#97
+ def object; end
+
+ # Transitions the current value of the object's states to those specified by
+ # each transition
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#140
+ def persist; end
+
+ # Resets any information tracked from previous attempts to perform the
+ # collection
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#116
+ def reset; end
+
+ # Rolls back changes made to the object's states via each transition
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#162
+ def rollback; end
+
+ # Runs the actions for each transition. If a block is given method, then it
+ # will be called instead of invoking each transition's action.
+ #
+ # The results of the actions will be used to determine #success?.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#148
+ def run_actions; end
+
+ # Runs each transition's callbacks recursively. Once all before callbacks
+ # have been executed, the transitions will then be persisted and the
+ # configured actions will be run.
+ #
+ # If any transition fails to run its callbacks, :halt will be thrown.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#126
+ def run_callbacks(index = T.unsafe(nil), &block); end
+
+ # Did each transition perform successfully? This will only be true if the
+ # following requirements are met:
+ # * No +before+ callbacks halt
+ # * All actions run successfully (always true if skipping actions)
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#92
+ def success?; end
+
+ # Determines whether an event attribute be used to trigger the transitions
+ # in this collection or whether the transitions be run directly *outside*
+ # of the action.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#110
+ def use_event_attributes?; end
+
+ # Is this a valid set of transitions? If the collection was creating with
+ # any +false+ values for transitions, then the the collection will be
+ # marked as invalid.
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#84
+ def valid?; end
+
+ # Runs a block within a transaction for the object being transitioned. If
+ # transactions are disabled, then this is a no-op.
+ #
+ # source://state_machines//lib/state_machines/transition_collection.rb#180
+ def within_transaction; end
+end
+
+# source://state_machines//lib/state_machines/version.rb#2
+StateMachines::VERSION = T.let(T.unsafe(nil), String)
+
+# Matches a specific set of values
+#
+# source://state_machines//lib/state_machines/matcher.rb#54
+class StateMachines::WhitelistMatcher < ::StateMachines::Matcher
+ # A human-readable description of this matcher
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#68
+ def description; end
+
+ # Checks whether the given value exists within the whitelist configured
+ # for this matcher.
+ #
+ # == Examples
+ #
+ # matcher = StateMachines::WhitelistMatcher.new([:parked, :idling])
+ # matcher.matches?(:parked) # => true
+ # matcher.matches?(:first_gear) # => false
+ #
+ # @return [Boolean]
+ #
+ # source://state_machines//lib/state_machines/matcher.rb#63
+ def matches?(value, context = T.unsafe(nil)); end
+end
diff --git a/sorbet/rbi/shims/tapioca.rbi b/sorbet/rbi/shims/tapioca.rbi
new file mode 100644
index 0000000..bcd9c7e
--- /dev/null
+++ b/sorbet/rbi/shims/tapioca.rbi
@@ -0,0 +1,13 @@
+# typed: true
+# frozen_string_literal: true
+
+module Tapioca
+ module Dsl
+ module Helpers
+ module ActiveRecordConstantsHelper
+ RelationMethodsModuleName = T.let(T.unsafe(nil), String)
+ AssociationRelationMethodsModuleName = T.let(T.unsafe(nil), String)
+ end
+ end
+ end
+end