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, field_name) ⇒ 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, field_name = nil) ⇒ 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
permalink #initialize(options = {}, &block) ⇒ Machine
Returns a new instance of Machine.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/machine.rb', line 62 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
permalink #events ⇒ Object (readonly)
Instance Methods
60 61 62 |
# File 'lib/machine.rb', line 60 def events @events end |
permalink #helpers ⇒ Object (readonly)
Instance Methods
60 61 62 |
# File 'lib/machine.rb', line 60 def helpers @helpers end |
permalink #hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
11 12 13 |
# File 'lib/machine.rb', line 11 def hooks @hooks end |
permalink #named_procs ⇒ Object (readonly)
Instance Methods
60 61 62 |
# File 'lib/machine.rb', line 60 def named_procs @named_procs end |
permalink #options ⇒ Object (readonly)
Instance Methods
60 61 62 |
# File 'lib/machine.rb', line 60 def @options end |
permalink #requirement_messages ⇒ Object (readonly)
Instance Methods
60 61 62 |
# File 'lib/machine.rb', line 60 def @requirement_messages end |
Class Method Details
permalink .bind!(machine, owner, name, field_name) ⇒ Object
make it so that a class which has included StateFu has a binding to this machine
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/machine.rb', line 33 def self.bind!( machine, owner, name, field_name) name = name.to_sym # define an accessor method with the given name if owner.class == Class owner.state_fu_machines[name] = machine owner.state_fu_field_names[name] = field_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 end end # prepare the persistence field StateFu::Persistence.prepare_field owner, field_name else _binding = StateFu::Binding.new machine, owner, name, :field_name => field_name, :singleton => true MethodFactory.define_singleton_method(owner, name) { _binding } end end |
permalink .BINDINGS ⇒ Object
[View source]
4 5 6 |
# File 'lib/machine.rb', line 4 def self.BINDINGS @@_bindings ||= {} end |
permalink .for_class(klass, name, options = {}, &block) ⇒ Object
Class methods
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 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, [:field_name] end if block_given? machine.apply! &block end machine end |
Instance Method Details
permalink #apply!(&block) ⇒ Object Also known as: lathe
merge the commands in &block with the existing machine; returns a lathe for the machine.
76 77 78 |
# File 'lib/machine.rb', line 76 def apply!( &block ) StateFu::Lathe.new( self, &block ) end |
permalink #bind!(owner, name = DEFAULT, field_name = nil) ⇒ Object
make it so a class which has included StateFu has a binding to this machine
119 120 121 122 |
# File 'lib/machine.rb', line 119 def bind!( owner, name= DEFAULT, field_name = nil ) field_name ||= Persistence.default_field_name( name ) self.class.bind!(self, owner, name, field_name) end |
permalink #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
170 171 172 |
# File 'lib/machine.rb', line 170 def deep_clone Marshal::load(Marshal.dump(self)) end |
permalink #empty? ⇒ Boolean
124 125 126 |
# File 'lib/machine.rb', line 124 def empty? states.empty? end |
permalink #event_names ⇒ Object
[View source]
149 150 151 |
# File 'lib/machine.rb', line 149 def event_names events.map(&:name) end |
permalink #find_or_create_states_by_name(*args) ⇒ Object
given a messy bunch of symbols, find or create a list of matching States.
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/machine.rb', line 155 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 |
permalink #graphviz ⇒ Object
[View source]
179 180 181 |
# File 'lib/machine.rb', line 179 def graphviz @graphviz ||= Plotter.new(self).output end |
permalink #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.
107 108 109 |
# File 'lib/machine.rb', line 107 def helper *modules_to_add modules_to_add.each { |mod| helpers << mod } end |
permalink #helper_modules ⇒ Object
[View source]
81 82 83 |
# File 'lib/machine.rb', line 81 def helper_modules helpers.modules end |
permalink #initial_state ⇒ Object
[View source]
141 142 143 |
# File 'lib/machine.rb', line 141 def initial_state() @initial_state ||= states.first end |
permalink #initial_state=(s) ⇒ Object
[View source]
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/machine.rb', line 128 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 |
permalink #inject_helpers_into(obj) ⇒ Object
[View source]
85 86 87 |
# File 'lib/machine.rb', line 85 def inject_helpers_into( obj ) helpers.inject_into( obj ) end |
permalink #inject_methods_into(obj) ⇒ Object
[View source]
93 94 95 |
# File 'lib/machine.rb', line 93 def inject_methods_into( obj ) #puts 'inject_methods_into' end |
permalink #inject_tools_into(obj) ⇒ Object
[View source]
89 90 91 |
# File 'lib/machine.rb', line 89 def inject_tools_into( obj ) tools.inject_into( obj ) end |
permalink #inspect ⇒ Object
[View source]
175 176 177 |
# File 'lib/machine.rb', line 175 def inspect "#<#{self.class} ##{__id__} states=#{state_names.inspect} events=#{event_names.inspect} options=#{.inspect}>" end |
permalink #state_names ⇒ Object
[View source]
145 146 147 |
# File 'lib/machine.rb', line 145 def state_names states.map(&:name) end |
permalink #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.
113 114 115 |
# File 'lib/machine.rb', line 113 def tool *modules_to_add modules_to_add.each { |mod| tools << mod } end |