array_logic 0.0.1 → 0.0.2
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.
- data/lib/array_logic/rule.rb +129 -128
- data/lib/array_logic/version.rb +1 -1
- metadata +1 -2
- data/lib/main.rb +0 -4
data/lib/array_logic/rule.rb
CHANGED
|
@@ -1,134 +1,135 @@
|
|
|
1
|
+
module ArrayLogic
|
|
2
|
+
class Rule
|
|
3
|
+
attr_accessor :rule
|
|
4
|
+
attr_reader :things
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
1
7
|
|
|
2
|
-
class Rule
|
|
3
|
-
attr_accessor :rule
|
|
4
|
-
attr_reader :things
|
|
5
|
-
|
|
6
|
-
def initialize
|
|
7
|
-
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def matches(*array_of_things)
|
|
11
|
-
array_of_things.delete_if{|things| !match(things)}
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def match(things)
|
|
15
|
-
rule_valid?
|
|
16
|
-
@things = things
|
|
17
|
-
logic
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def logic
|
|
21
|
-
eval(expression)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def rule_valid?
|
|
25
|
-
check_rule_entered
|
|
26
|
-
check_allowed_characters
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def replace_item(pattern, processor)
|
|
30
|
-
@processed_rule = processed_rule.gsub(pattern) {|x| processor.call(x)}
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
def thing_ids
|
|
35
|
-
things.collect(&:id)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def expression
|
|
39
|
-
rule_processing_steps
|
|
40
|
-
return final_processed_rule
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def rule_processing_steps
|
|
46
|
-
add_space_around_puctuation_characters
|
|
47
|
-
make_everything_lower_case
|
|
48
|
-
replace_logic_words_with_operators
|
|
49
|
-
replace_item(thing_id_pattern, true_or_false_for_thing_id_in_thing_ids)
|
|
50
|
-
replace_item(number_in_set_pattern, comparison_of_number_with_true_count)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def number_in_set_pattern
|
|
54
|
-
/\d+\s+in\s+((true|false)[\,\s]*)+/
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def comparison_of_number_with_true_count
|
|
58
|
-
lambda do |string|
|
|
59
|
-
before_in, after_in = string.split(/\s+in\s+/)
|
|
60
|
-
true_count = after_in.split.count('true')
|
|
61
|
-
" ( #{before_in} <= #{true_count} ) "
|
|
62
8
|
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# examples: a1, a2, a33, t1
|
|
66
|
-
def thing_id_pattern
|
|
67
|
-
/\w\d+/
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def true_or_false_for_thing_id_in_thing_ids
|
|
71
|
-
lambda {|s| thing_ids.include?(s[/\d+/].to_i)}
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def processed_rule
|
|
75
|
-
@processed_rule ||= rule.clone
|
|
76
|
-
end
|
|
77
9
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
10
|
+
def matches(*array_of_things)
|
|
11
|
+
array_of_things.delete_if{|things| !match(things)}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def match(things)
|
|
15
|
+
rule_valid?
|
|
16
|
+
@things = things
|
|
17
|
+
logic
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def logic
|
|
21
|
+
eval(expression)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def rule_valid?
|
|
25
|
+
check_rule_entered
|
|
26
|
+
check_allowed_characters
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def replace_item(pattern, processor)
|
|
30
|
+
@processed_rule = processed_rule.gsub(pattern) {|x| processor.call(x)}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
def thing_ids
|
|
35
|
+
things.collect(&:id)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def expression
|
|
39
|
+
rule_processing_steps
|
|
40
|
+
return final_processed_rule
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def rule_processing_steps
|
|
46
|
+
add_space_around_puctuation_characters
|
|
47
|
+
make_everything_lower_case
|
|
48
|
+
replace_logic_words_with_operators
|
|
49
|
+
replace_item(thing_id_pattern, true_or_false_for_thing_id_in_thing_ids)
|
|
50
|
+
replace_item(number_in_set_pattern, comparison_of_number_with_true_count)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def number_in_set_pattern
|
|
54
|
+
/\d+\s+in\s+((true|false)[\,\s]*)+/
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def comparison_of_number_with_true_count
|
|
58
|
+
lambda do |string|
|
|
59
|
+
before_in, after_in = string.split(/\s+in\s+/)
|
|
60
|
+
true_count = after_in.split.count('true')
|
|
61
|
+
" ( #{before_in} <= #{true_count} ) "
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# examples: a1, a2, a33, t1
|
|
66
|
+
def thing_id_pattern
|
|
67
|
+
/\w\d+/
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def true_or_false_for_thing_id_in_thing_ids
|
|
71
|
+
lambda {|s| thing_ids.include?(s[/\d+/].to_i)}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def processed_rule
|
|
75
|
+
@processed_rule ||= rule.clone
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def add_space_around_puctuation_characters
|
|
79
|
+
@processed_rule = processed_rule.gsub(/(\)|\)|\,)/, ' \1 ')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def make_everything_lower_case
|
|
83
|
+
@processed_rule = processed_rule.downcase
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def replace_logic_words_with_operators
|
|
87
|
+
{
|
|
88
|
+
'and' => '&&',
|
|
89
|
+
'or' => '||',
|
|
90
|
+
'not' => '!'
|
|
91
|
+
}.each{|word, operator| @processed_rule = processed_rule.gsub(Regexp.new(word), operator)}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def final_processed_rule
|
|
95
|
+
result = processed_rule.clone
|
|
96
|
+
reset_processed_rule_ready_for_next_comparison
|
|
97
|
+
return result
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def reset_processed_rule_ready_for_next_comparison
|
|
101
|
+
@processed_rule = nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def check_rule_entered
|
|
105
|
+
raise "You must define a rule before trying to match" unless rule.kind_of? String
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def check_allowed_characters
|
|
109
|
+
raise_invalid_charachers unless allowed_charachers_pattern =~ rule
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def allowed_charachers_pattern
|
|
113
|
+
case_insensitive = true
|
|
114
|
+
Regexp.new("^(#{allowed_characters.join('|')})*$", case_insensitive)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def allowed_characters
|
|
118
|
+
brackets = ['\(', '\)']
|
|
119
|
+
in_pattern = ['\d+\s+in']
|
|
120
|
+
ids = ['\w\d+']
|
|
121
|
+
logic_words = %w{and or not}
|
|
122
|
+
logic_chrs = ['&&', '\|\|', '!']
|
|
123
|
+
commas = ['\,']
|
|
124
|
+
white_space = ['\s']
|
|
125
|
+
|
|
126
|
+
[brackets, in_pattern, ids, logic_words, logic_chrs, commas, white_space].flatten
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def raise_invalid_charachers
|
|
130
|
+
invalid = rule.split.collect{|s| (allowed_charachers_pattern =~ s) ? nil : s }.compact
|
|
131
|
+
raise "The rule '#{rule}' is not valid. The problem is within '#{invalid.join(' ')}'"
|
|
132
|
+
end
|
|
85
133
|
|
|
86
|
-
def replace_logic_words_with_operators
|
|
87
|
-
{
|
|
88
|
-
'and' => '&&',
|
|
89
|
-
'or' => '||',
|
|
90
|
-
'not' => '!'
|
|
91
|
-
}.each{|word, operator| @processed_rule = processed_rule.gsub(Regexp.new(word), operator)}
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def final_processed_rule
|
|
95
|
-
result = processed_rule.clone
|
|
96
|
-
reset_processed_rule_ready_for_next_comparison
|
|
97
|
-
return result
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def reset_processed_rule_ready_for_next_comparison
|
|
101
|
-
@processed_rule = nil
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def check_rule_entered
|
|
105
|
-
raise "You must define a rule before trying to match" unless rule.kind_of? String
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def check_allowed_characters
|
|
109
|
-
raise_invalid_charachers unless allowed_charachers_pattern =~ rule
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def allowed_charachers_pattern
|
|
113
|
-
case_insensitive = true
|
|
114
|
-
Regexp.new("^(#{allowed_characters.join('|')})*$", case_insensitive)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def allowed_characters
|
|
118
|
-
brackets = ['\(', '\)']
|
|
119
|
-
in_pattern = ['\d+\s+in']
|
|
120
|
-
ids = ['\w\d+']
|
|
121
|
-
logic_words = %w{and or not}
|
|
122
|
-
logic_chrs = ['&&', '\|\|', '!']
|
|
123
|
-
commas = ['\,']
|
|
124
|
-
white_space = ['\s']
|
|
125
|
-
|
|
126
|
-
[brackets, in_pattern, ids, logic_words, logic_chrs, commas, white_space].flatten
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def raise_invalid_charachers
|
|
130
|
-
invalid = rule.split.collect{|s| (allowed_charachers_pattern =~ s) ? nil : s }.compact
|
|
131
|
-
raise "The rule '#{rule}' is not valid. The problem is within '#{invalid.join(' ')}'"
|
|
132
134
|
end
|
|
133
|
-
|
|
134
135
|
end
|
data/lib/array_logic/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: array_logic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -20,7 +20,6 @@ extensions: []
|
|
|
20
20
|
extra_rdoc_files: []
|
|
21
21
|
files:
|
|
22
22
|
- lib/array_logic.rb
|
|
23
|
-
- lib/main.rb
|
|
24
23
|
- lib/array_logic/thing.rb
|
|
25
24
|
- lib/array_logic/version.rb
|
|
26
25
|
- lib/array_logic/rule.rb
|
data/lib/main.rb
DELETED