reflekt 1.0.3 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/{Accessor.rb → accessor.rb} +2 -0
- data/lib/{Execution.rb → action.rb} +14 -12
- data/lib/action_stack.rb +46 -0
- data/lib/{Clone.rb → clone.rb} +6 -4
- data/lib/{Config.rb → config.rb} +3 -1
- data/lib/{Control.rb → control.rb} +16 -12
- data/lib/experiment.rb +83 -0
- data/lib/{Meta.rb → meta.rb} +7 -5
- data/lib/meta/{ArrayMeta.rb → array_meta.rb} +3 -1
- data/lib/meta/{BooleanMeta.rb → boolean_meta.rb} +3 -1
- data/lib/meta/{FloatMeta.rb → float_meta.rb} +3 -1
- data/lib/meta/{IntegerMeta.rb → integer_meta.rb} +3 -1
- data/lib/meta/{NullMeta.rb → null_meta.rb} +4 -2
- data/lib/meta/{StringMeta.rb → string_meta.rb} +3 -1
- data/lib/{MetaBuilder.rb → meta_builder.rb} +4 -2
- data/lib/reflection.rb +150 -0
- data/lib/{Reflekt.rb → reflekt.rb} +42 -42
- data/lib/{Renderer.rb → renderer.rb} +2 -0
- data/lib/{Rule.rb → rule.rb} +3 -1
- data/lib/{RuleSet.rb → rule_set.rb} +5 -3
- data/lib/{Aggregator.rb → rule_set_aggregator.rb} +29 -18
- data/lib/rules/{ArrayRule.rb → array_rule.rb} +3 -1
- data/lib/rules/{BooleanRule.rb → boolean_rule.rb} +3 -1
- data/lib/rules/{FloatRule.rb → float_rule.rb} +3 -1
- data/lib/rules/{IntegerRule.rb → integer_rule.rb} +3 -1
- data/lib/rules/{NullRule.rb → null_rule.rb} +5 -6
- data/lib/rules/{StringRule.rb → string_rule.rb} +3 -1
- data/lib/web/bundle.js +2 -2
- data/lib/web/package-lock.json +3 -3
- data/lib/web/package.json +1 -1
- data/lib/web/server.js +5 -5
- metadata +30 -29
- data/lib/Reflection.rb +0 -193
- data/lib/ShadowStack.rb +0 -44
| @@ -5,13 +5,14 @@ | |
| 5 5 | 
             
            #   A "null" value on serialized "inputs" and "output" also becomes a NullMeta.
         | 
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            # @hierachy
         | 
| 8 | 
            -
            #   1.  | 
| 8 | 
            +
            #   1. Action
         | 
| 9 9 | 
             
            #   2. Reflection
         | 
| 10 10 | 
             
            #   3. Meta <- YOU ARE HERE
         | 
| 11 11 | 
             
            ################################################################################
         | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 13 | 
            +
            require_relative '../meta'
         | 
| 14 14 |  | 
| 15 | 
            +
            module Reflekt
         | 
| 15 16 | 
             
            class NullMeta < Meta
         | 
| 16 17 |  | 
| 17 18 | 
             
              def initialize()
         | 
| @@ -32,3 +33,4 @@ class NullMeta < Meta | |
| 32 33 | 
             
              end
         | 
| 33 34 |  | 
| 34 35 | 
             
            end
         | 
| 36 | 
            +
            end
         | 
| @@ -5,10 +5,11 @@ | |
| 5 5 | 
             
            # @see lib/meta for each meta.
         | 
| 6 6 | 
             
            ################################################################################
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 8 | 
            +
            require_relative 'meta'
         | 
| 9 9 | 
             
            # Require all meta.
         | 
| 10 | 
            -
            Dir[File.join(__dir__, 'meta', '*.rb')].each { |file|  | 
| 10 | 
            +
            Dir[File.join(__dir__, 'meta', '*.rb')].each { |file| require_relative file }
         | 
| 11 11 |  | 
| 12 | 
            +
            module Reflekt
         | 
| 12 13 | 
             
            class MetaBuilder
         | 
| 13 14 |  | 
| 14 15 | 
             
              ##
         | 
| @@ -82,3 +83,4 @@ class MetaBuilder | |
| 82 83 | 
             
              end
         | 
| 83 84 |  | 
| 84 85 | 
             
            end
         | 
| 86 | 
            +
            end
         | 
    
        data/lib/reflection.rb
    ADDED
    
    | @@ -0,0 +1,150 @@ | |
| 1 | 
            +
            ################################################################################
         | 
| 2 | 
            +
            # A snapshot of real or random data.
         | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # @pattern Abstract class
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # @nomenclature
         | 
| 7 | 
            +
            #   args, inputs/output and meta represent different stages of a value.
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # @hierachy
         | 
| 10 | 
            +
            #   1. Action
         | 
| 11 | 
            +
            #   2. Reflection <- YOU ARE HERE
         | 
| 12 | 
            +
            #   3. Meta
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # @status
         | 
| 15 | 
            +
            #   - :pass [Symbol] The reflection passes the rules.
         | 
| 16 | 
            +
            #   - :fail [Symbol] The reflection fails the rules or produces a system error.
         | 
| 17 | 
            +
            #   - :error [Symbol] The control reflection produces a system error.
         | 
| 18 | 
            +
            ################################################################################
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            require_relative 'clone'
         | 
| 21 | 
            +
            require_relative 'meta_builder'
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            module Reflekt
         | 
| 24 | 
            +
            class Reflection
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              attr_reader :status
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              ##
         | 
| 29 | 
            +
              # Create a reflection.
         | 
| 30 | 
            +
              #
         | 
| 31 | 
            +
              # @param action [Action] The Action that created this Reflection.
         | 
| 32 | 
            +
              # @param number [Integer] Multiple Reflections can be created per Action.
         | 
| 33 | 
            +
              # @param aggregator [RuleSetAggregator] The aggregated RuleSet for this class/method.
         | 
| 34 | 
            +
              ##
         | 
| 35 | 
            +
              def initialize(action, number, aggregator)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                @action = action
         | 
| 38 | 
            +
                @unique_id = action.unique_id + number
         | 
| 39 | 
            +
                @number = number
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                # Dependency.
         | 
| 42 | 
            +
                @aggregator = aggregator
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                # Caller.
         | 
| 45 | 
            +
                @klass = action.klass
         | 
| 46 | 
            +
                @method = action.method
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                # Metadata.
         | 
| 49 | 
            +
                @inputs = nil
         | 
| 50 | 
            +
                @output = nil
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                # Clone the action's calling object.
         | 
| 53 | 
            +
                # TODO: Abstract away into Clone class.
         | 
| 54 | 
            +
                @clone = action.caller_object.clone
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                # Result.
         | 
| 57 | 
            +
                @status = :pass
         | 
| 58 | 
            +
                @time = Time.now.to_i
         | 
| 59 | 
            +
                @message = nil
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              ##
         | 
| 64 | 
            +
              # Reflect on a method.
         | 
| 65 | 
            +
              #
         | 
| 66 | 
            +
              # Create a shadow action.
         | 
| 67 | 
            +
              # @param *args [Dynamic] The method's arguments.
         | 
| 68 | 
            +
              ##
         | 
| 69 | 
            +
              def reflect(*args)
         | 
| 70 | 
            +
                # Implemented by Control and Experiment.
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              ##
         | 
| 74 | 
            +
              # Create random values for each argument from control reflections.
         | 
| 75 | 
            +
              #
         | 
| 76 | 
            +
              # @param args [Dynamic] The arguments to mirror random values for.
         | 
| 77 | 
            +
              # @param input_rule_sets [Array] Aggregated rule sets for each argument.
         | 
| 78 | 
            +
              #
         | 
| 79 | 
            +
              # @return [Dynamic] Random arguments.
         | 
| 80 | 
            +
              ##
         | 
| 81 | 
            +
              def randomize(args, input_rule_sets)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                random_args = []
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                args.each_with_index do |arg, arg_num|
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  # Get a random rule in the rule set.
         | 
| 88 | 
            +
                  rules = input_rule_sets[arg_num].rules
         | 
| 89 | 
            +
                  agg_rule = rules[rules.keys.sample]
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  # Create a random value that follows that rule.
         | 
| 92 | 
            +
                  random_args << agg_rule.random()
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                return random_args
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              ##
         | 
| 101 | 
            +
              # Get the results of the reflection.
         | 
| 102 | 
            +
              #
         | 
| 103 | 
            +
              # @keys
         | 
| 104 | 
            +
              #   - eid [Integer] Execution ID
         | 
| 105 | 
            +
              #   - aid [Integer] Action ID
         | 
| 106 | 
            +
              #   - rid [Integer] Reflection ID
         | 
| 107 | 
            +
              #   - num [Integer] Reflection number
         | 
| 108 | 
            +
              #
         | 
| 109 | 
            +
              # @return [Hash] Reflection metadata.
         | 
| 110 | 
            +
              ##
         | 
| 111 | 
            +
              def serialize()
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                # Create execution ID from the ID of the first action in   the ActionStack.
         | 
| 114 | 
            +
                execution_id = @action.unique_id
         | 
| 115 | 
            +
                unless @action.base.nil?
         | 
| 116 | 
            +
                  execution_id = @action.base.unique_id
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                # Build reflection.
         | 
| 120 | 
            +
                reflection = {
         | 
| 121 | 
            +
                  :eid => execution_id,
         | 
| 122 | 
            +
                  :aid => @action.unique_id,
         | 
| 123 | 
            +
                  :rid => @unique_id,
         | 
| 124 | 
            +
                  :num => @number,
         | 
| 125 | 
            +
                  :time => @time,
         | 
| 126 | 
            +
                  :class => @klass,
         | 
| 127 | 
            +
                  :method => @method,
         | 
| 128 | 
            +
                  :status => @status,
         | 
| 129 | 
            +
                  :message => @message,
         | 
| 130 | 
            +
                  :inputs => nil,
         | 
| 131 | 
            +
                  :output => nil,
         | 
| 132 | 
            +
                }
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                unless @inputs.nil?
         | 
| 135 | 
            +
                  reflection[:inputs] = []
         | 
| 136 | 
            +
                  @inputs.each do |meta|
         | 
| 137 | 
            +
                    reflection[:inputs] << meta.serialize()
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                unless @output.nil?
         | 
| 142 | 
            +
                  reflection[:output] = @output.serialize()
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                return reflection
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
            end
         | 
| 150 | 
            +
            end
         | 
| @@ -6,8 +6,8 @@ | |
| 6 6 | 
             
            # @flow
         | 
| 7 7 | 
             
            #   1. Reflekt is prepended to a class and setup.
         | 
| 8 8 | 
             
            #   2. When a class insantiates so does Reflekt.
         | 
| 9 | 
            -
            #   3. An  | 
| 10 | 
            -
            #   4. Many Refections are created per  | 
| 9 | 
            +
            #   3. An Action is created on method call.
         | 
| 10 | 
            +
            #   4. Many Refections are created per Action.
         | 
| 11 11 | 
             
            #   5. Each Reflection executes on cloned data.
         | 
| 12 12 | 
             
            #   6. Flow is returned to the original method.
         | 
| 13 13 | 
             
            #
         | 
| @@ -19,16 +19,16 @@ | |
| 19 19 | 
             
            require 'set'
         | 
| 20 20 | 
             
            require 'erb'
         | 
| 21 21 | 
             
            require 'rowdb'
         | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 22 | 
            +
            require_relative 'accessor'
         | 
| 23 | 
            +
            require_relative 'action'
         | 
| 24 | 
            +
            require_relative 'action_stack'
         | 
| 25 | 
            +
            require_relative 'config'
         | 
| 26 | 
            +
            require_relative 'control'
         | 
| 27 | 
            +
            require_relative 'experiment'
         | 
| 28 | 
            +
            require_relative 'renderer'
         | 
| 29 | 
            +
            require_relative 'rule_set_aggregator'
         | 
| 30 30 | 
             
            # Require all rules.
         | 
| 31 | 
            -
            Dir[File.join(__dir__, 'rules', '*.rb')].each { |file|  | 
| 31 | 
            +
            Dir[File.join(__dir__, 'rules', '*.rb')].each { |file| require_relative file }
         | 
| 32 32 |  | 
| 33 33 | 
             
            module Reflekt
         | 
| 34 34 |  | 
| @@ -53,34 +53,34 @@ module Reflekt | |
| 53 53 | 
             
                    # When Reflekt enabled and control reflection has executed without error.
         | 
| 54 54 | 
             
                    if @@reflekt.config.enabled && !@@reflekt.error
         | 
| 55 55 |  | 
| 56 | 
            -
                      # Get current  | 
| 57 | 
            -
                       | 
| 56 | 
            +
                      # Get current action.
         | 
| 57 | 
            +
                      action = @@reflekt.stack.peek()
         | 
| 58 58 |  | 
| 59 59 | 
             
                      # Don't reflect when reflect limit reached or method skipped.
         | 
| 60 60 | 
             
                      unless (@reflekt_counts[method] >= @@reflekt.config.reflect_limit) || self.class.reflekt_skipped?(method)
         | 
| 61 61 |  | 
| 62 | 
            -
                        # When stack empty or past  | 
| 63 | 
            -
                        if  | 
| 62 | 
            +
                        # When stack empty or past action done reflecting.
         | 
| 63 | 
            +
                        if action.nil? || action.has_finished_reflecting?
         | 
| 64 64 |  | 
| 65 | 
            -
                          # Create  | 
| 66 | 
            -
                           | 
| 65 | 
            +
                          # Create action.
         | 
| 66 | 
            +
                          action = Action.new(self, method, @@reflekt.config.reflect_amount, @@reflekt.stack)
         | 
| 67 67 |  | 
| 68 | 
            -
                          @@reflekt.stack.push( | 
| 68 | 
            +
                          @@reflekt.stack.push(action)
         | 
| 69 69 |  | 
| 70 70 | 
             
                        end
         | 
| 71 71 |  | 
| 72 72 | 
             
                        ##
         | 
| 73 | 
            -
                        # Reflect the  | 
| 73 | 
            +
                        # Reflect the action.
         | 
| 74 74 | 
             
                        #
         | 
| 75 | 
            -
                        # The first method call in the  | 
| 76 | 
            -
                        # Then method calls are shadow  | 
| 75 | 
            +
                        # The first method call in the action creates a reflection.
         | 
| 76 | 
            +
                        # Then method calls are shadow actions which return to the reflection.
         | 
| 77 77 | 
             
                        ##
         | 
| 78 | 
            -
                        if  | 
| 79 | 
            -
                           | 
| 78 | 
            +
                        if action.has_empty_experiments? && !action.is_reflecting?
         | 
| 79 | 
            +
                          action.is_reflecting = true
         | 
| 80 80 |  | 
| 81 81 | 
             
                          # Create control.
         | 
| 82 | 
            -
                          control = Control.new( | 
| 83 | 
            -
                           | 
| 82 | 
            +
                          control = Control.new(action, 0, @@reflekt.aggregator)
         | 
| 83 | 
            +
                          action.control = control
         | 
| 84 84 |  | 
| 85 85 | 
             
                          # Execute control.
         | 
| 86 86 | 
             
                          control.reflect(*args)
         | 
| @@ -91,22 +91,22 @@ module Reflekt | |
| 91 91 | 
             
                          # Continue reflecting when control executes succesfully.
         | 
| 92 92 | 
             
                          else
         | 
| 93 93 |  | 
| 94 | 
            -
                            # Save control as reflection.
         | 
| 94 | 
            +
                            # Save control as a reflection.
         | 
| 95 95 | 
             
                            @@reflekt.db.get("reflections").push(control.serialize())
         | 
| 96 96 |  | 
| 97 | 
            -
                            # Multiple  | 
| 98 | 
            -
                             | 
| 97 | 
            +
                            # Multiple experiments per action.
         | 
| 98 | 
            +
                            action.experiments.each_with_index do |value, index|
         | 
| 99 99 |  | 
| 100 | 
            -
                              # Create  | 
| 101 | 
            -
                               | 
| 102 | 
            -
                               | 
| 100 | 
            +
                              # Create experiment.
         | 
| 101 | 
            +
                              experiment = Experiment.new(action, index + 1, @@reflekt.aggregator)
         | 
| 102 | 
            +
                              action.experiments[index] = experiment
         | 
| 103 103 |  | 
| 104 | 
            -
                              # Execute  | 
| 105 | 
            -
                               | 
| 104 | 
            +
                              # Execute experiment.
         | 
| 105 | 
            +
                              experiment.reflect(*args)
         | 
| 106 106 | 
             
                              @reflekt_counts[method] = @reflekt_counts[method] + 1
         | 
| 107 107 |  | 
| 108 | 
            -
                              # Save  | 
| 109 | 
            -
                              @@reflekt.db.get("reflections").push( | 
| 108 | 
            +
                              # Save experiment.
         | 
| 109 | 
            +
                              @@reflekt.db.get("reflections").push(experiment.serialize())
         | 
| 110 110 |  | 
| 111 111 | 
             
                            end
         | 
| 112 112 |  | 
| @@ -121,15 +121,15 @@ module Reflekt | |
| 121 121 |  | 
| 122 122 | 
             
                          end
         | 
| 123 123 |  | 
| 124 | 
            -
                           | 
| 124 | 
            +
                          action.is_reflecting = false
         | 
| 125 125 | 
             
                        end
         | 
| 126 126 |  | 
| 127 127 | 
             
                      end
         | 
| 128 128 |  | 
| 129 129 | 
             
                      # Don't execute skipped methods when reflecting.
         | 
| 130 | 
            -
                      unless  | 
| 130 | 
            +
                      unless action.is_reflecting? && self.class.reflekt_skipped?(method)
         | 
| 131 131 |  | 
| 132 | 
            -
                        # Continue  | 
| 132 | 
            +
                        # Continue action / shadow action.
         | 
| 133 133 | 
             
                        super *args
         | 
| 134 134 |  | 
| 135 135 | 
             
                      end
         | 
| @@ -137,7 +137,7 @@ module Reflekt | |
| 137 137 | 
             
                    # When Reflekt disabled or control reflection failed.
         | 
| 138 138 | 
             
                    else
         | 
| 139 139 |  | 
| 140 | 
            -
                      # Continue  | 
| 140 | 
            +
                      # Continue action.
         | 
| 141 141 | 
             
                      super *args
         | 
| 142 142 |  | 
| 143 143 | 
             
                    end
         | 
| @@ -180,7 +180,7 @@ module Reflekt | |
| 180 180 | 
             
                # Set configuration.
         | 
| 181 181 | 
             
                @@reflekt.path = File.dirname(File.realpath(__FILE__))
         | 
| 182 182 |  | 
| 183 | 
            -
                # Get reflections directory path from config or current  | 
| 183 | 
            +
                # Get reflections directory path from config or current action path.
         | 
| 184 184 | 
             
                if @@reflekt.config.output_path
         | 
| 185 185 | 
             
                  @@reflekt.output_path = File.join(@@reflekt.config.output_path, @@reflekt.config.output_directory)
         | 
| 186 186 | 
             
                else
         | 
| @@ -199,10 +199,10 @@ module Reflekt | |
| 199 199 | 
             
                db = @@reflekt.db.value()
         | 
| 200 200 |  | 
| 201 201 | 
             
                # Create shadow stack.
         | 
| 202 | 
            -
                @@reflekt.stack =  | 
| 202 | 
            +
                @@reflekt.stack = ActionStack.new()
         | 
| 203 203 |  | 
| 204 204 | 
             
                # Create aggregated rule sets.
         | 
| 205 | 
            -
                @@reflekt.aggregator =  | 
| 205 | 
            +
                @@reflekt.aggregator = RuleSetAggregator.new(@@reflekt.config.meta_map)
         | 
| 206 206 | 
             
                @@reflekt.aggregator.train(db[:controls])
         | 
| 207 207 |  | 
| 208 208 | 
             
                # Create renderer.
         | 
    
        data/lib/{Rule.rb → rule.rb}
    RENAMED
    
    | @@ -4,13 +4,14 @@ | |
| 4 4 | 
             
            # @pattern Abstract class
         | 
| 5 5 | 
             
            #
         | 
| 6 6 | 
             
            # @hierachy
         | 
| 7 | 
            -
            #   1.  | 
| 7 | 
            +
            #   1. RuleSetAggregator
         | 
| 8 8 | 
             
            #   2. RuleSet
         | 
| 9 9 | 
             
            #   3. Rule <- YOU ARE HERE
         | 
| 10 10 | 
             
            #
         | 
| 11 11 | 
             
            # @see lib/rules for rules.
         | 
| 12 12 | 
             
            ################################################################################
         | 
| 13 13 |  | 
| 14 | 
            +
            module Reflekt
         | 
| 14 15 | 
             
            class Rule
         | 
| 15 16 |  | 
| 16 17 | 
             
              attr_reader :type
         | 
| @@ -50,3 +51,4 @@ class Rule | |
| 50 51 | 
             
              end
         | 
| 51 52 |  | 
| 52 53 | 
             
            end
         | 
| 54 | 
            +
            end
         | 
| @@ -6,15 +6,16 @@ | |
| 6 6 | 
             
            #   - Builder
         | 
| 7 7 | 
             
            #
         | 
| 8 8 | 
             
            # @hierachy
         | 
| 9 | 
            -
            #   1.  | 
| 9 | 
            +
            #   1. RuleSetAggregator
         | 
| 10 10 | 
             
            #   2. RuleSet <- YOU ARE HERE
         | 
| 11 11 | 
             
            #   3. Rule
         | 
| 12 12 | 
             
            ################################################################################
         | 
| 13 13 |  | 
| 14 14 | 
             
            require 'set'
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            require_relative ' | 
| 15 | 
            +
            require_relative 'meta_builder'
         | 
| 16 | 
            +
            require_relative 'meta/null_meta.rb'
         | 
| 17 17 |  | 
| 18 | 
            +
            module Reflekt
         | 
| 18 19 | 
             
            class RuleSet
         | 
| 19 20 |  | 
| 20 21 | 
             
              attr_accessor :rules
         | 
| @@ -107,3 +108,4 @@ class RuleSet | |
| 107 108 |  | 
| 108 109 |  | 
| 109 110 | 
             
            end
         | 
| 111 | 
            +
            end
         | 
| @@ -5,14 +5,15 @@ | |
| 5 5 | 
             
            # @pattern Singleton
         | 
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            # @hierachy
         | 
| 8 | 
            -
            #   1.  | 
| 8 | 
            +
            #   1. RuleSetAggregator <- YOU ARE HERE
         | 
| 9 9 | 
             
            #   2. RuleSet
         | 
| 10 10 | 
             
            #   3. Rule
         | 
| 11 11 | 
             
            ################################################################################
         | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 13 | 
            +
            require_relative 'rule_set'
         | 
| 14 14 |  | 
| 15 | 
            -
             | 
| 15 | 
            +
            module Reflekt
         | 
| 16 | 
            +
            class RuleSetAggregator
         | 
| 16 17 |  | 
| 17 18 | 
             
              ##
         | 
| 18 19 | 
             
              # @param meta_map [Hash] The rules that apply to each meta type.
         | 
| @@ -46,21 +47,13 @@ class Aggregator | |
| 46 47 | 
             
                  # INPUT
         | 
| 47 48 | 
             
                  ##
         | 
| 48 49 |  | 
| 49 | 
            -
                   | 
| 50 | 
            +
                  # Singular null input.
         | 
| 51 | 
            +
                  if control["inputs"].nil?
         | 
| 52 | 
            +
                    train_input(klass, method, nil, 0)
         | 
| 53 | 
            +
                  # Multiple inputs.
         | 
| 54 | 
            +
                  else
         | 
| 50 55 | 
             
                    control["inputs"].each_with_index do |meta, arg_num|
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                      meta = Meta.deserialize(meta)
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                      # Get rule set.
         | 
| 55 | 
            -
                      rule_set = get_input_rule_set(klass, method, arg_num)
         | 
| 56 | 
            -
                      if rule_set.nil?
         | 
| 57 | 
            -
                        rule_set = RuleSet.new(@meta_map)
         | 
| 58 | 
            -
                        set_input_rule_set(klass, method, arg_num, rule_set)
         | 
| 59 | 
            -
                      end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                      # Train on metadata.
         | 
| 62 | 
            -
                      rule_set.train(meta)
         | 
| 63 | 
            -
             | 
| 56 | 
            +
                      train_input(klass, method, meta, arg_num)
         | 
| 64 57 | 
             
                    end
         | 
| 65 58 | 
             
                  end
         | 
| 66 59 |  | 
| @@ -82,10 +75,27 @@ class Aggregator | |
| 82 75 |  | 
| 83 76 | 
             
              end
         | 
| 84 77 |  | 
| 78 | 
            +
              def train_input(klass, method, meta, arg_num)
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                # Get deserialized meta.
         | 
| 81 | 
            +
                meta = Meta.deserialize(meta)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                # Get rule set.
         | 
| 84 | 
            +
                rule_set = get_input_rule_set(klass, method, arg_num)
         | 
| 85 | 
            +
                if rule_set.nil?
         | 
| 86 | 
            +
                  rule_set = RuleSet.new(@meta_map)
         | 
| 87 | 
            +
                  set_input_rule_set(klass, method, arg_num, rule_set)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                # Train on metadata.
         | 
| 91 | 
            +
                rule_set.train(meta)
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
             | 
| 85 95 | 
             
              ##
         | 
| 86 96 | 
             
              # Validate inputs.
         | 
| 87 97 | 
             
              #
         | 
| 88 | 
            -
              # @stage Called when validating a reflection.
         | 
| 98 | 
            +
              # @stage Called when validating a control reflection.
         | 
| 89 99 | 
             
              # @param inputs [Array] The method's arguments.
         | 
| 90 100 | 
             
              # @param input_rule_sets [Array] The RuleSets to validate each input with.
         | 
| 91 101 | 
             
              ##
         | 
| @@ -249,3 +259,4 @@ class Aggregator | |
| 249 259 | 
             
              end
         | 
| 250 260 |  | 
| 251 261 | 
             
            end
         | 
| 262 | 
            +
            end
         |