reflekt 1.0.9 → 1.0.10
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 +33 -27
- data/lib/action.rb +108 -71
- data/lib/action_stack.rb +29 -31
- data/lib/clone.rb +10 -12
- data/lib/config.rb +44 -41
- data/lib/control.rb +44 -48
- data/lib/experiment.rb +63 -74
- data/lib/meta.rb +50 -48
- data/lib/meta/array_meta.rb +26 -30
- data/lib/meta/boolean_meta.rb +17 -19
- data/lib/meta/float_meta.rb +17 -19
- data/lib/meta/integer_meta.rb +17 -19
- data/lib/meta/null_meta.rb +19 -19
- data/lib/meta/string_meta.rb +17 -19
- data/lib/meta_builder.rb +74 -74
- data/lib/reflection.rb +91 -91
- data/lib/reflekt.rb +160 -126
- data/lib/renderer.rb +27 -30
- data/lib/rule.rb +33 -33
- data/lib/rule_set.rb +64 -65
- data/lib/rule_set_aggregator.rb +191 -193
- data/lib/rules/array_rule.rb +77 -73
- data/lib/rules/boolean_rule.rb +29 -35
- data/lib/rules/float_rule.rb +42 -46
- data/lib/rules/integer_rule.rb +42 -46
- data/lib/rules/null_rule.rb +30 -30
- data/lib/rules/string_rule.rb +54 -62
- data/lib/web/index.html +3 -4
- metadata +17 -3
data/lib/rule.rb
CHANGED
@@ -12,43 +12,43 @@
|
|
12
12
|
################################################################################
|
13
13
|
|
14
14
|
module Reflekt
|
15
|
-
class Rule
|
15
|
+
class Rule
|
16
16
|
|
17
|
-
|
17
|
+
attr_reader :type
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
##
|
20
|
+
# Each rule trains on metadata to determine its boundaries.
|
21
|
+
#
|
22
|
+
# @param meta [Meta]
|
23
|
+
##
|
24
|
+
def train(meta)
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
##
|
28
|
+
# Each rule validates a value with its boundaries.
|
29
|
+
#
|
30
|
+
# @param value [Dynamic]
|
31
|
+
# @return [Boolean] Whether the value passes or fails.
|
32
|
+
##
|
33
|
+
def test(value)
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
##
|
37
|
+
# Each rule provides results.
|
38
|
+
#
|
39
|
+
# @return [Hash]
|
40
|
+
##
|
41
|
+
def result()
|
42
|
+
{}
|
43
|
+
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
##
|
46
|
+
# Each rule provides a random example that matches the rule's boundaries.
|
47
|
+
#
|
48
|
+
# @return [Dynamic] A random value.
|
49
|
+
##
|
50
|
+
def random()
|
51
|
+
end
|
52
52
|
|
53
|
-
end
|
53
|
+
end
|
54
54
|
end
|
data/lib/rule_set.rb
CHANGED
@@ -16,96 +16,95 @@ require_relative 'meta_builder'
|
|
16
16
|
require_relative 'meta/null_meta.rb'
|
17
17
|
|
18
18
|
module Reflekt
|
19
|
-
class RuleSet
|
19
|
+
class RuleSet
|
20
20
|
|
21
|
-
|
21
|
+
attr_accessor :rules
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
##
|
24
|
+
# @param meta_map [Hash] The rules to apply to each data type.
|
25
|
+
##
|
26
|
+
def initialize(meta_map)
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
# The rules that apply to meta types.
|
29
|
+
@meta_map = meta_map
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
# The types of meta this rule set applies to.
|
32
|
+
# Rules are only validated on their supported meta type.
|
33
|
+
@meta_types = Set.new()
|
34
34
|
|
35
|
-
|
35
|
+
@rules = {}
|
36
36
|
|
37
|
-
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
##
|
40
|
+
# Train rule set on metadata.
|
41
|
+
#
|
42
|
+
# @param meta [Hash] The metadata to train on.
|
43
|
+
##
|
44
|
+
def train(meta)
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
# Track supported meta types.
|
47
|
+
meta_type = meta[:type]
|
48
|
+
@meta_types << meta_type
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
# Get rule types for this meta type.
|
51
|
+
if @meta_map.key? meta_type
|
52
|
+
@meta_map[meta_type].each do |rule_type|
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
# Ensure rule exists.
|
55
|
+
if @rules[rule_type].nil?
|
56
|
+
@rules[rule_type] = rule_type.new()
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
# Train rule.
|
60
|
+
@rules[rule_type].train(meta)
|
61
61
|
|
62
|
+
end
|
62
63
|
end
|
63
|
-
end
|
64
64
|
|
65
|
-
|
65
|
+
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
##
|
68
|
+
# @param value [Dynamic]
|
69
|
+
##
|
70
|
+
def test(value)
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
result = true
|
73
|
+
meta_type = MetaBuilder.data_type_to_meta_type(value)
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
# Fail if value's meta type not testable by rule set.
|
76
|
+
unless @meta_types.include? meta_type
|
77
|
+
return false
|
78
|
+
end
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
@rules.each do |klass, rule|
|
81
|
+
if (rule.type == meta_type)
|
82
|
+
unless rule.test(value)
|
83
|
+
result = false
|
84
|
+
end
|
84
85
|
end
|
85
86
|
end
|
86
|
-
end
|
87
|
-
|
88
|
-
return result
|
89
87
|
|
90
|
-
|
88
|
+
return result
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Get the results of the rules.
|
94
|
+
#
|
95
|
+
# @return [Array] The rules.
|
96
|
+
##
|
97
|
+
def result()
|
98
|
+
|
99
|
+
rules = {}
|
100
|
+
|
101
|
+
@rules.each do |key, rule|
|
102
|
+
rules[rule.class] = rule.result()
|
103
|
+
end
|
98
104
|
|
99
|
-
|
105
|
+
return rules
|
100
106
|
|
101
|
-
@rules.each do |key, rule|
|
102
|
-
rules[rule.class] = rule.result()
|
103
107
|
end
|
104
108
|
|
105
|
-
return rules
|
106
|
-
|
107
109
|
end
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
110
|
end
|
data/lib/rule_set_aggregator.rb
CHANGED
@@ -13,250 +13,248 @@
|
|
13
13
|
require_relative 'rule_set'
|
14
14
|
|
15
15
|
module Reflekt
|
16
|
-
class RuleSetAggregator
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
class RuleSetAggregator
|
17
|
+
|
18
|
+
##
|
19
|
+
# @param meta_map [Hash] The rules that apply to each meta type.
|
20
|
+
##
|
21
|
+
def initialize(meta_map)
|
22
|
+
@meta_map = meta_map
|
23
|
+
# Key rule sets by class and method.
|
24
|
+
@rule_sets = {}
|
25
|
+
end
|
22
26
|
|
23
|
-
|
24
|
-
#
|
25
|
-
|
27
|
+
##
|
28
|
+
# Create aggregated rule sets from control metadata.
|
29
|
+
#
|
30
|
+
# @stage Called on setup.
|
31
|
+
# @param controls [Array] Controls with metadata.
|
32
|
+
# @TODO Revert string keys to symbols once "Fix Rowdb.get(path)" bug fixed.
|
33
|
+
##
|
34
|
+
def train(controls)
|
35
|
+
|
36
|
+
# On first use there are no previous controls.
|
37
|
+
return if controls.nil?
|
38
|
+
|
39
|
+
controls.each do |control|
|
40
|
+
|
41
|
+
klass = control["class"].to_sym
|
42
|
+
method = control["method"].to_sym
|
43
|
+
|
44
|
+
##
|
45
|
+
# INPUT
|
46
|
+
##
|
47
|
+
|
48
|
+
# Singular null input.
|
49
|
+
if control["inputs"].nil?
|
50
|
+
train_input(klass, method, nil, 0)
|
51
|
+
# Multiple inputs.
|
52
|
+
else
|
53
|
+
control["inputs"].each_with_index do |meta, arg_num|
|
54
|
+
train_input(klass, method, meta, arg_num)
|
55
|
+
end
|
56
|
+
end
|
26
57
|
|
27
|
-
|
58
|
+
##
|
59
|
+
# OUTPUT
|
60
|
+
##
|
28
61
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# @TODO Revert string keys to symbols once "Fix Rowdb.get(path)" bug fixed.
|
35
|
-
##
|
36
|
-
def train(controls)
|
37
|
-
|
38
|
-
# On first use there are no previous controls.
|
39
|
-
return if controls.nil?
|
40
|
-
|
41
|
-
controls.each do |control|
|
42
|
-
|
43
|
-
klass = control["class"].to_sym
|
44
|
-
method = control["method"].to_sym
|
45
|
-
|
46
|
-
##
|
47
|
-
# INPUT
|
48
|
-
##
|
49
|
-
|
50
|
-
# Singular null input.
|
51
|
-
if control["inputs"].nil?
|
52
|
-
train_input(klass, method, nil, 0)
|
53
|
-
# Multiple inputs.
|
54
|
-
else
|
55
|
-
control["inputs"].each_with_index do |meta, arg_num|
|
56
|
-
train_input(klass, method, meta, arg_num)
|
62
|
+
# Get rule set.
|
63
|
+
output_rule_set = get_output_rule_set(klass, method)
|
64
|
+
if output_rule_set.nil?
|
65
|
+
output_rule_set = RuleSet.new(@meta_map)
|
66
|
+
set_output_rule_set(klass, method, output_rule_set)
|
57
67
|
end
|
58
|
-
end
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
##
|
69
|
+
# Train on metadata.
|
70
|
+
output_rule_set.train(Meta.deserialize(control["output"]))
|
63
71
|
|
64
|
-
# Get rule set.
|
65
|
-
output_rule_set = get_output_rule_set(klass, method)
|
66
|
-
if output_rule_set.nil?
|
67
|
-
output_rule_set = RuleSet.new(@meta_map)
|
68
|
-
set_output_rule_set(klass, method, output_rule_set)
|
69
72
|
end
|
70
73
|
|
71
|
-
# Train on metadata.
|
72
|
-
output_rule_set.train(Meta.deserialize(control["output"]))
|
73
|
-
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
def train_input(klass, method, meta, arg_num)
|
77
77
|
|
78
|
-
|
78
|
+
# Get deserialized meta.
|
79
|
+
meta = Meta.deserialize(meta)
|
80
|
+
|
81
|
+
# Get rule set.
|
82
|
+
rule_set = get_input_rule_set(klass, method, arg_num)
|
83
|
+
if rule_set.nil?
|
84
|
+
rule_set = RuleSet.new(@meta_map)
|
85
|
+
set_input_rule_set(klass, method, arg_num, rule_set)
|
86
|
+
end
|
79
87
|
|
80
|
-
|
81
|
-
|
88
|
+
# Train on metadata.
|
89
|
+
rule_set.train(meta)
|
82
90
|
|
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
91
|
end
|
89
92
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
##
|
94
|
+
# Validate inputs.
|
95
|
+
#
|
96
|
+
# @stage Called when validating a control reflection.
|
97
|
+
# @param inputs [Array] The method's arguments.
|
98
|
+
# @param input_rule_sets [Array] The RuleSets to validate each input with.
|
99
|
+
##
|
100
|
+
def test_inputs(inputs, input_rule_sets)
|
94
101
|
|
95
|
-
|
96
|
-
|
97
|
-
#
|
98
|
-
# @stage Called when validating a control reflection.
|
99
|
-
# @param inputs [Array] The method's arguments.
|
100
|
-
# @param input_rule_sets [Array] The RuleSets to validate each input with.
|
101
|
-
##
|
102
|
-
def test_inputs(inputs, input_rule_sets)
|
102
|
+
# Default result to PASS.
|
103
|
+
result = true
|
103
104
|
|
104
|
-
|
105
|
-
|
105
|
+
# Validate each argument against each rule set for that argument.
|
106
|
+
inputs.each_with_index do |input, arg_num|
|
106
107
|
|
107
|
-
|
108
|
-
inputs.each_with_index do |input, arg_num|
|
108
|
+
unless input_rule_sets[arg_num].nil?
|
109
109
|
|
110
|
-
|
110
|
+
rule_set = input_rule_sets[arg_num]
|
111
111
|
|
112
|
-
|
112
|
+
unless rule_set.test(input)
|
113
|
+
result = false
|
114
|
+
end
|
113
115
|
|
114
|
-
unless rule_set.test(input)
|
115
|
-
result = false
|
116
116
|
end
|
117
|
-
|
118
117
|
end
|
119
|
-
end
|
120
118
|
|
121
|
-
|
119
|
+
return result
|
122
120
|
|
123
|
-
|
121
|
+
end
|
124
122
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
##
|
124
|
+
# Validate output.
|
125
|
+
#
|
126
|
+
# @stage Called when validating a reflection.
|
127
|
+
# @param output [Dynamic] The method's return value.
|
128
|
+
# @param output_rule_set [RuleSet] The rule set to validate the output with.
|
129
|
+
##
|
130
|
+
def test_output(output, output_rule_set)
|
133
131
|
|
134
|
-
|
135
|
-
|
132
|
+
# Default to a PASS result.
|
133
|
+
result = true
|
136
134
|
|
137
|
-
|
135
|
+
unless output_rule_set.nil?
|
136
|
+
|
137
|
+
# Validate output rule set for that argument.
|
138
|
+
unless output_rule_set.test(output)
|
139
|
+
result = false
|
140
|
+
end
|
138
141
|
|
139
|
-
# Validate output RuleSet for that argument.
|
140
|
-
unless output_rule_set.test(output)
|
141
|
-
result = false
|
142
142
|
end
|
143
143
|
|
144
|
-
|
144
|
+
return result
|
145
145
|
|
146
|
-
|
146
|
+
end
|
147
147
|
|
148
|
-
|
148
|
+
##
|
149
|
+
# Get aggregated RuleSets for all inputs.
|
150
|
+
#
|
151
|
+
# @stage Called when building a reflection.
|
152
|
+
# @param klass [Symbol]
|
153
|
+
# @param method [Symbol]
|
154
|
+
# @return [Array]
|
155
|
+
##
|
156
|
+
def get_input_rule_sets(klass, method)
|
157
|
+
@rule_sets.dig(klass, method, :inputs)
|
158
|
+
end
|
149
159
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
160
|
+
##
|
161
|
+
# Get an aggregated RuleSet for an output.
|
162
|
+
#
|
163
|
+
# @stage Called when building a reflection.
|
164
|
+
# @param klass [Symbol]
|
165
|
+
# @param method [Symbol]
|
166
|
+
# @return [RuleSet]
|
167
|
+
##
|
168
|
+
def get_output_rule_set(klass, method)
|
169
|
+
@rule_sets.dig(klass, method, :output)
|
170
|
+
end
|
161
171
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
# @param klass [Symbol]
|
167
|
-
# @param method [Symbol]
|
168
|
-
# @return [RuleSet]
|
169
|
-
##
|
170
|
-
def get_output_rule_set(klass, method)
|
171
|
-
@rule_sets.dig(klass, method, :output)
|
172
|
-
end
|
172
|
+
##
|
173
|
+
# Get the base rule type for a data type.
|
174
|
+
##
|
175
|
+
def self.value_to_rule_type(value)
|
173
176
|
|
174
|
-
|
175
|
-
# Get the base rule type for a data type.
|
176
|
-
##
|
177
|
-
def self.value_to_rule_type(value)
|
177
|
+
data_type = value.class
|
178
178
|
|
179
|
-
|
179
|
+
rule_types = {
|
180
|
+
Array => ArrayRule,
|
181
|
+
TrueClass => BooleanRule,
|
182
|
+
FalseClass => BooleanRule,
|
183
|
+
Float => FloatRule,
|
184
|
+
Integer => IntegerRule,
|
185
|
+
NilClass => NullRule,
|
186
|
+
String => StringRule
|
187
|
+
}
|
180
188
|
|
181
|
-
|
182
|
-
Array => ArrayRule,
|
183
|
-
TrueClass => BooleanRule,
|
184
|
-
FalseClass => BooleanRule,
|
185
|
-
Float => FloatRule,
|
186
|
-
Integer => IntegerRule,
|
187
|
-
NilClass => NullRule,
|
188
|
-
String => StringRule
|
189
|
-
}
|
189
|
+
return rule_types[data_type]
|
190
190
|
|
191
|
-
|
191
|
+
end
|
192
192
|
|
193
|
-
|
193
|
+
def self.testable?(args, input_rule_sets)
|
194
194
|
|
195
|
-
|
195
|
+
args.each_with_index do |arg, arg_num|
|
196
196
|
|
197
|
-
|
197
|
+
rule_type = value_to_rule_type(arg)
|
198
|
+
if input_rule_sets[arg_num].rules[rule_type].nil?
|
199
|
+
return false
|
200
|
+
end
|
198
201
|
|
199
|
-
rule_type = value_to_rule_type(arg)
|
200
|
-
if input_rule_sets[arg_num].rules[rule_type].nil?
|
201
|
-
return false
|
202
202
|
end
|
203
203
|
|
204
|
-
|
204
|
+
return true
|
205
205
|
|
206
|
-
|
206
|
+
end
|
207
207
|
|
208
|
-
|
208
|
+
##############################################################################
|
209
|
+
# HELPERS
|
210
|
+
##############################################################################
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
##
|
215
|
+
# Get an aggregated RuleSet for an input.
|
216
|
+
#
|
217
|
+
# @param klass [Symbol]
|
218
|
+
# @param method [Symbol]
|
219
|
+
# @return [RuleSet]
|
220
|
+
##
|
221
|
+
def get_input_rule_set(klass, method, arg_num)
|
222
|
+
@rule_sets.dig(klass, method, :inputs, arg_num)
|
223
|
+
end
|
209
224
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
@rule_sets.dig(klass, method, :inputs, arg_num)
|
225
|
-
end
|
225
|
+
##
|
226
|
+
# Set an aggregated RuleSet for an input.
|
227
|
+
#
|
228
|
+
# @param klass [Symbol]
|
229
|
+
# @param method [Symbol]
|
230
|
+
##
|
231
|
+
def set_input_rule_set(klass, method, arg_num, rule_set)
|
232
|
+
|
233
|
+
# Set defaults.
|
234
|
+
@rule_sets[klass] = {} unless @rule_sets.key? klass
|
235
|
+
@rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
|
236
|
+
@rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
|
237
|
+
# Set value.
|
238
|
+
@rule_sets[klass][method][:inputs][arg_num] = rule_set
|
226
239
|
|
227
|
-
|
228
|
-
# Set an aggregated RuleSet for an input.
|
229
|
-
#
|
230
|
-
# @param klass [Symbol]
|
231
|
-
# @param method [Symbol]
|
232
|
-
##
|
233
|
-
def set_input_rule_set(klass, method, arg_num, rule_set)
|
234
|
-
|
235
|
-
# Set defaults.
|
236
|
-
@rule_sets[klass] = {} unless @rule_sets.key? klass
|
237
|
-
@rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
|
238
|
-
@rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
|
239
|
-
# Set value.
|
240
|
-
@rule_sets[klass][method][:inputs][arg_num] = rule_set
|
240
|
+
end
|
241
241
|
|
242
|
-
|
242
|
+
##
|
243
|
+
# Set an aggregated RuleSet for an output.
|
244
|
+
#
|
245
|
+
# @param klass [Symbol]
|
246
|
+
# @param method [Symbol]
|
247
|
+
# @param rule_set [RuleSet]
|
248
|
+
##
|
249
|
+
def set_output_rule_set(klass, method, rule_set)
|
250
|
+
|
251
|
+
# Set defaults.
|
252
|
+
@rule_sets[klass] = {} unless @rule_sets.key? klass
|
253
|
+
@rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
|
254
|
+
# Set value.
|
255
|
+
@rule_sets[klass][method][:output] = rule_set
|
243
256
|
|
244
|
-
|
245
|
-
# Set an aggregated RuleSet for an output.
|
246
|
-
#
|
247
|
-
# @param klass [Symbol]
|
248
|
-
# @param method [Symbol]
|
249
|
-
# @param rule_set [RuleSet]
|
250
|
-
##
|
251
|
-
def set_output_rule_set(klass, method, rule_set)
|
252
|
-
|
253
|
-
# Set defaults.
|
254
|
-
@rule_sets[klass] = {} unless @rule_sets.key? klass
|
255
|
-
@rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
|
256
|
-
# Set value.
|
257
|
-
@rule_sets[klass][method][:output] = rule_set
|
257
|
+
end
|
258
258
|
|
259
259
|
end
|
260
|
-
|
261
|
-
end
|
262
260
|
end
|