Class: StateFu::Machine
- Includes:
- HasOptions, Applicable
- Defined in:
- lib/machine.rb
Instance Attribute Summary collapse
-
#events ⇒ Object
readonly
Instance Methods.
-
#helpers ⇒ Object
readonly
Instance Methods.
-
#hooks ⇒ Object
readonly
Returns the value of attribute hooks.
-
#named_procs ⇒ Object
readonly
Instance Methods.
-
#options ⇒ Object
readonly
Instance Methods.
-
#requirement_messages ⇒ Object
readonly
Instance Methods.
-
#states ⇒ Object
readonly
Instance Methods.
-
#tools ⇒ Object
readonly
Instance Methods.
Class Method Summary collapse
-
.bind!(machine, owner, name, options = {}) ⇒ Object
make it so that a class which has included StateFu has a binding to this machine.
- .BINDINGS ⇒ Object
-
.for_class(klass, name, options = {}, &block) ⇒ Object
Class methods.
Instance Method Summary collapse
-
#apply!(&block) ⇒ Object
(also: #lathe)
merge the commands in &block with the existing machine; returns a lathe for the machine.
-
#bind!(owner, name = DEFAULT, options = {}) ⇒ Object
make it so a class which has included StateFu has a binding to this machine.
-
#deep_clone ⇒ Object
(also: #deep_copy)
Marshal, the poor man’s X-Ray photocopier.
- #empty? ⇒ Boolean
- #event_names ⇒ Object
-
#find_or_create_states_by_name(*args) ⇒ Object
given a messy bunch of symbols, find or create a list of matching States.
- #graphviz ⇒ Object
-
#helper(*modules_to_add) ⇒ Object
the modules listed here will be mixed into Binding and Transition objects for this machine.
- #helper_modules ⇒ Object
- #initial_state ⇒ Object
- #initial_state=(s) ⇒ Object
-
#initialize(options = {}, &block) ⇒ Machine
constructor
A new instance of Machine.
- #inject_helpers_into(obj) ⇒ Object
- #inject_methods_into(obj) ⇒ Object
- #inject_tools_into(obj) ⇒ Object
- #inspect ⇒ Object
- #state_names ⇒ Object
-
#tool(*modules_to_add) ⇒ Object
same as helper, but for extending Lathes rather than the Bindings / Transitions.
Methods included from HasOptions
Methods included from Applicable
Constructor Details
#initialize(options = {}, &block) ⇒ Machine
Returns a new instance of Machine.
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/machine.rb', line 71 def initialize( ={}, &block ) @states = [].extend( StateArray ) @events = [].extend( EventArray ) @helpers = [].extend( HelperArray ) @tools = [].extend( ToolArray ) @named_procs = {} @requirement_messages = {} @options = @hooks = Hooks.for( self ) apply!( &block ) if block_given? end |
Instance Attribute Details
#events ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def events @events end |
#helpers ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def helpers @helpers end |
#hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
11 12 13 |
# File 'lib/machine.rb', line 11 def hooks @hooks end |
#named_procs ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def named_procs @named_procs end |
#options ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def @options end |
#requirement_messages ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def @requirement_messages end |
#states ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def states @states end |
#tools ⇒ Object (readonly)
Instance Methods
69 70 71 |
# File 'lib/machine.rb', line 69 def tools @tools end |
Class Method Details
.bind!(machine, owner, name, options = {}) ⇒ Object
make it so that a class which has included StateFu has a binding to this machine
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/machine.rb', line 32 def self.bind!(machine, owner, name, ={}) name = name.to_sym [:define_methods] = (name == DEFAULT) unless .symbolize_keys!.has_key?(:define_methods) [:field_name] ||= Persistence.default_field_name(name) [:singleton] = true unless owner.is_a?(Class) # define an accessor method with the given name if [:singleton] _binding = StateFu::Binding.new machine, owner, name, MethodFactory.define_singleton_method(owner, name) { _binding } if alias_name = [:alias] || [:as] MethodFactory.define_singleton_method(owner, alias_name) { _binding } end else owner.state_fu_machines[name] = machine owner.[name] = # method_missing to catch NoMethodError for event methods, etc StateFu::MethodFactory.define_once_only_method_missing owner unless owner.respond_to? name owner.class_eval do define_method name do state_fu name end # allow aliases to be set up, e.g. machine(:as => :status) if alias_name = [:alias] || [:as] alias_method alias_name, name end end end # prepare the persistence field StateFu::Persistence.prepare_field owner, [:field_name] end end |
.BINDINGS ⇒ Object
4 5 6 |
# File 'lib/machine.rb', line 4 def self.BINDINGS @@_bindings ||= {} end |
.for_class(klass, name, options = {}, &block) ⇒ Object
Class methods
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/machine.rb', line 17 def self.for_class(klass, name, ={}, &block) .symbolize_keys! name = name.to_sym unless machine = klass.state_fu_machines[ name ] machine = new() machine.bind! klass, name, end if block_given? machine.apply! &block end machine end |
Instance Method Details
#apply!(&block) ⇒ Object Also known as: lathe
merge the commands in &block with the existing machine; returns a lathe for the machine.
85 86 87 |
# File 'lib/machine.rb', line 85 def apply!( &block ) StateFu::Lathe.new( self, &block ) end |
#bind!(owner, name = DEFAULT, options = {}) ⇒ Object
make it so a class which has included StateFu has a binding to this machine
128 129 130 |
# File 'lib/machine.rb', line 128 def bind!(owner, name=DEFAULT, ={}) self.class.bind!(self, owner, name, ) end |
#deep_clone ⇒ Object Also known as: deep_copy
Marshal, the poor man’s X-Ray photocopier. TODO: a version which will not break its teeth on procs
178 179 180 |
# File 'lib/machine.rb', line 178 def deep_clone Marshal::load(Marshal.dump(self)) end |
#empty? ⇒ Boolean
132 133 134 |
# File 'lib/machine.rb', line 132 def empty? states.empty? end |
#event_names ⇒ Object
157 158 159 |
# File 'lib/machine.rb', line 157 def event_names events.map(&:name) end |
#find_or_create_states_by_name(*args) ⇒ Object
given a messy bunch of symbols, find or create a list of matching States.
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/machine.rb', line 163 def find_or_create_states_by_name( *args ) args = args.compact.flatten raise ArgumentError.new( args.inspect ) unless args.all? { |a| [Symbol, StateFu::State].include? a.class } args.map do |s| unless state = states[s.to_sym] # TODO clean this line up state = s.is_a?( StateFu::State ) ? s : StateFu::State.new( self, s ) self.states << state end state end end |
#graphviz ⇒ Object
187 188 189 |
# File 'lib/machine.rb', line 187 def graphviz @graphviz ||= Plotter.new(self).output end |
#helper(*modules_to_add) ⇒ Object
the modules listed here will be mixed into Binding and Transition objects for this machine. use this to define methods, references or data useful to you during transitions, event hooks, or in general use of StateFu.
They can be supplied as a string/symbol (as per rails controller helpers), or a Module.
To do this globally, just duck-punch StateFu::Machine / StateFu::Binding.
116 117 118 |
# File 'lib/machine.rb', line 116 def helper *modules_to_add modules_to_add.each { |mod| helpers << mod } end |
#helper_modules ⇒ Object
90 91 92 |
# File 'lib/machine.rb', line 90 def helper_modules helpers.modules end |
#initial_state ⇒ Object
149 150 151 |
# File 'lib/machine.rb', line 149 def initial_state() @initial_state ||= states.first end |
#initial_state=(s) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/machine.rb', line 136 def initial_state=( s ) case s when Symbol, String, StateFu::State unless init_state = states[ s.to_sym ] init_state = StateFu::State.new( self, s.to_sym ) states << init_state end @initial_state = init_state else raise( ArgumentError, s.inspect ) end end |
#inject_helpers_into(obj) ⇒ Object
94 95 96 |
# File 'lib/machine.rb', line 94 def inject_helpers_into( obj ) helpers.inject_into( obj ) end |
#inject_methods_into(obj) ⇒ Object
102 103 104 |
# File 'lib/machine.rb', line 102 def inject_methods_into( obj ) #puts 'inject_methods_into' end |
#inject_tools_into(obj) ⇒ Object
98 99 100 |
# File 'lib/machine.rb', line 98 def inject_tools_into( obj ) tools.inject_into( obj ) end |
#inspect ⇒ Object
183 184 185 |
# File 'lib/machine.rb', line 183 def inspect "#<#{self.class} ##{__id__} states=#{state_names.inspect} events=#{event_names.inspect} options=#{.inspect}>" end |
#state_names ⇒ Object
153 154 155 |
# File 'lib/machine.rb', line 153 def state_names states.map(&:name) end |
#tool(*modules_to_add) ⇒ Object
same as helper, but for extending Lathes rather than the Bindings / Transitions. use this to extend the Lathe DSL to suit your problem domain.
122 123 124 |
# File 'lib/machine.rb', line 122 def tool *modules_to_add modules_to_add.each { |mod| tools << mod } end |