Class: LSystem::ProductionAdapter
- Inherits:
-
Object
- Object
- LSystem::ProductionAdapter
- Extended by:
- Loggability
- Defined in:
- lib/l_system/production_adapter.rb
Overview
An adapter that connects method calls to an LSystem::RulesEngine’s generations.
Instance Attribute Summary collapse
-
#production_map ⇒ Object
readonly
The map of symbols to production methods.
Class Method Summary collapse
-
.inherited(subclass) ⇒ Object
Inheritance callback – add class-instance variables to the
subclass
. -
.on_finish(&block) ⇒ Object
Register a callback that will be called at the end of each new generation.
-
.on_start(&block) ⇒ Object
Register a callback that will be called at the start of each new generation.
-
.production_map(productions = {}) ⇒ Object
Declare a Hash of symbols to methods that should be called when one appears in a generation.
-
.production_map=(new_map) ⇒ Object
Set the Hash of symbols to methods that should be called when one appears in a generation.
-
.result(&block) ⇒ Object
Register a callback that will be called to obtain the result of running a generation.
Instance Method Summary collapse
-
#initialize ⇒ ProductionAdapter
constructor
Create a new instance of the ProductionAdapter.
-
#make_dispatch_table ⇒ Object
Return a Hash of symbols to bound Methods to call for their productions from the current #production_map.
-
#run(rules_engine, iterations) ⇒ Object
Run productions for each generation produced by the given
rules_engine
up toiterations
times. -
#run_generation(generation) ⇒ Object
Run the specified
generation
by calling productions for each of its symbols.
Constructor Details
#initialize ⇒ ProductionAdapter
Create a new instance of the ProductionAdapter.
84 85 86 |
# File 'lib/l_system/production_adapter.rb', line 84 def initialize @production_map = self.class.production_map end |
Instance Attribute Details
#production_map ⇒ Object (readonly)
The map of symbols to production methods
95 96 97 |
# File 'lib/l_system/production_adapter.rb', line 95 def production_map @production_map end |
Class Method Details
.inherited(subclass) ⇒ Object
Inheritance callback – add class-instance variables to the subclass
.
20 21 22 23 24 25 |
# File 'lib/l_system/production_adapter.rb', line 20 def self::inherited( subclass ) super subclass.instance_variable_set( :@production_map, {} ) subclass.instance_variable_set( :@callbacks, {} ) end |
.on_finish(&block) ⇒ Object
Register a callback that will be called at the end of each new generation. It will be called with the result of the this generation, which will be nil
if no #result callback is declared.
73 74 75 76 |
# File 'lib/l_system/production_adapter.rb', line 73 def self::on_finish( &block ) self.log.debug "Declaring on_finish callback: %p" % [ block ] define_method( :on_finish, &block ) end |
.on_start(&block) ⇒ Object
Register a callback that will be called at the start of each new generation. It will be called with the result of the last generation, or nil
if this is the 0th (axiom) generation.
53 54 55 56 |
# File 'lib/l_system/production_adapter.rb', line 53 def self::on_start( &block ) self.log.debug "Declaring on_start callback: %p" % [ block ] define_method( :on_start, &block ) end |
.production_map(productions = {}) ⇒ Object
Declare a Hash of symbols to methods that should be called when one appears in a generation.
34 35 36 37 38 39 40 |
# File 'lib/l_system/production_adapter.rb', line 34 def self::production_map( productions={} ) unless productions.empty? self.production_map = productions end return @production_map end |
.production_map=(new_map) ⇒ Object
Set the Hash of symbols to methods that should be called when one appears in a generation.
45 46 47 |
# File 'lib/l_system/production_adapter.rb', line 45 def self::production_map=( new_map ) @production_map.replace( new_map ) end |
.result(&block) ⇒ Object
Register a callback that will be called to obtain the result of running a generation. The result of calling the block
will be passed to this generation’s #on_finish callback (if there is one), the next generation’s #on_start callback (if there is one and there’s successive geneation), and returned from #run if this was the last generation.
64 65 66 67 |
# File 'lib/l_system/production_adapter.rb', line 64 def self::result( &block ) self.log.debug "Declaring result callback: %p" % [ block ] define_method( :result, &block ) end |
Instance Method Details
#make_dispatch_table ⇒ Object
Return a Hash of symbols to bound Methods to call for their productions from the current #production_map.
140 141 142 143 144 |
# File 'lib/l_system/production_adapter.rb', line 140 def make_dispatch_table return self.class.production_map.each_with_object( {} ) do |(symbol, method_name), hash| hash[ symbol ] = self.method( method_name ) end end |
#run(rules_engine, iterations) ⇒ Object
Run productions for each generation produced by the given rules_engine
up to iterations
times.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/l_system/production_adapter.rb', line 100 def run( rules_engine, iterations ) self.log.debug "Running %p for up to %d iterations" % [ rules_engine, iterations ] return rules_engine.each.with_index.inject( nil ) do |result, (generation, i)| self.log.debug "Running generation %d" % [ i ] self.on_start( i, result ) if self.respond_to?( :on_start ) self.run_generation( generation ) result = self.result( i ) if self.respond_to?( :result ) self.log.debug "Result [%d] is: %p" % [ i, result ] self.on_finish( i, result ) if self.respond_to?( :on_finish ) break result if i >= iterations - 1 result end end |
#run_generation(generation) ⇒ Object
Run the specified generation
by calling productions for each of its symbols.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/l_system/production_adapter.rb', line 119 def run_generation( generation ) # Make a new one every time to support self-mutating adapters dispatch_table = self.make_dispatch_table generation.each_char do |symbol| callback = dispatch_table[ symbol ] unless callback self.log.warn "No production for symbol %p" % [ symbol ] next end self.log.debug "%p -> %p" % [ symbol, callback ] callback.call end end |