array_logic 0.2.1 → 0.2.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 +20 -21
- data/lib/array_logic/version.rb +10 -5
- data/test/array_logic/rule_test.rb +6 -4
- metadata +2 -2
data/lib/array_logic/rule.rb
CHANGED
@@ -52,7 +52,11 @@ module ArrayLogic
|
|
52
52
|
|
53
53
|
private
|
54
54
|
def logic
|
55
|
-
|
55
|
+
begin
|
56
|
+
eval(expression)
|
57
|
+
rescue SyntaxError
|
58
|
+
raise "Unable to determine logic from this expression : #{expression}"
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
def match_ids(ids)
|
@@ -82,9 +86,9 @@ module ArrayLogic
|
|
82
86
|
end
|
83
87
|
|
84
88
|
def rule_processing_steps
|
85
|
-
replace_item(function_pattern, value_of_function_called_on_id_objects)
|
86
89
|
add_space_around_puctuation_characters
|
87
90
|
make_everything_lower_case
|
91
|
+
replace_item(function_pattern, build_logic_from_function_statement)
|
88
92
|
replace_logic_words_with_operators
|
89
93
|
replace_item(thing_id_pattern, ids_include_this_id)
|
90
94
|
replace_item(number_in_set_pattern, comparison_of_number_with_true_count)
|
@@ -117,34 +121,29 @@ module ArrayLogic
|
|
117
121
|
end
|
118
122
|
|
119
123
|
def function_pattern
|
120
|
-
|
124
|
+
function_name_pattern = array_functions.keys.join('|')
|
125
|
+
instance_function_pattern = '\w+[\?\!]?' # e.g. 'id', 'this!', 'that?', 'foo_bar'
|
126
|
+
comparison_pattern ='(==|[\<\>]=?|!=)\s*\d+(\.\d+)?' # e.g. '== 4.3', '> 4'
|
127
|
+
/(#{function_name_pattern})\(\s*\:(#{instance_function_pattern})\s*\)\s*(#{comparison_pattern})/
|
121
128
|
end
|
122
129
|
|
123
130
|
def array_functions
|
124
131
|
{
|
125
|
-
:sum => '
|
126
|
-
:average => 'reduce(
|
132
|
+
:sum => 'reduce(0){|sum,x| x.respond_to?(:to_f) ? sum + x.to_f : sum }',
|
133
|
+
:average => 'reduce(0){|sum,x| x.respond_to?(:to_f) ? sum + x.to_f : sum } / size',
|
127
134
|
:count => 'compact.size'
|
128
135
|
}
|
129
136
|
end
|
130
137
|
|
131
|
-
def
|
138
|
+
def build_logic_from_function_statement
|
132
139
|
lambda do |string|
|
133
|
-
|
134
|
-
values = things.collect &
|
135
|
-
numbers_booleans_or_nils?(values)
|
140
|
+
array_function, instance_function, comparison = function_pattern.match(string).to_a[1, 3]
|
141
|
+
values = things.collect &instance_function.to_sym
|
136
142
|
result = values.instance_eval(array_functions[array_function.to_sym])
|
137
|
-
"( #{result} #{
|
143
|
+
"( #{result} #{comparison} )"
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
141
|
-
def numbers_booleans_or_nils?(values)
|
142
|
-
errors = values.reject{|v| v.nil? || v.is_a?(Numeric) || !!v == v}
|
143
|
-
unless errors.empty?
|
144
|
-
raise "Values must be numbers or nils. The problem is here: #{errors.join(", ")}"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
147
|
def processed_rule
|
149
148
|
@processed_rule ||= rule.clone
|
150
149
|
end
|
@@ -200,13 +199,13 @@ module ArrayLogic
|
|
200
199
|
def allowed_characters
|
201
200
|
{
|
202
201
|
:brackets => ['\(', '\)'],
|
203
|
-
:in_pattern =>
|
202
|
+
:in_pattern => '\d+\s+in',
|
204
203
|
:ids => [thing_id_pattern],
|
205
204
|
:logic_words => %w{and or not},
|
206
205
|
:logic_chrs => ['&&', '\|\|', '!'],
|
207
|
-
:commas =>
|
208
|
-
:white_space =>
|
209
|
-
:function_pattern =>
|
206
|
+
:commas => '\,',
|
207
|
+
:white_space => '\s',
|
208
|
+
:function_pattern => function_pattern
|
210
209
|
}
|
211
210
|
end
|
212
211
|
|
data/lib/array_logic/version.rb
CHANGED
@@ -1,24 +1,29 @@
|
|
1
1
|
module ArrayLogic
|
2
|
-
VERSION = "0.2.
|
2
|
+
VERSION = "0.2.2"
|
3
3
|
end
|
4
4
|
|
5
5
|
# History
|
6
6
|
# =======
|
7
7
|
#
|
8
|
+
# Version 0.2.2
|
9
|
+
# -------------
|
10
|
+
# Refactor to allow functions to be more flexible. That's is, to handle unexpected
|
11
|
+
# input, rather than just rejecting it.
|
12
|
+
#
|
8
13
|
# Version 0.2.1
|
9
|
-
#
|
14
|
+
# -------------
|
10
15
|
# Improved handling of errors in functions and add != operator
|
11
16
|
#
|
12
17
|
# Version 0.2.0
|
13
|
-
#
|
18
|
+
# -------------
|
14
19
|
# Adds functions: sum, count and average
|
15
20
|
#
|
16
21
|
# Version 0.1.2
|
17
|
-
#
|
22
|
+
# -------------
|
18
23
|
# Refactor to tidy up code and make private, rule methods that don't need exposing
|
19
24
|
#
|
20
25
|
#
|
21
26
|
# Version 0.1.1
|
22
|
-
#
|
27
|
+
# -------------
|
23
28
|
# Working version. No history before this point
|
24
29
|
#
|
@@ -298,10 +298,12 @@ module ArrayLogic
|
|
298
298
|
end
|
299
299
|
|
300
300
|
def test_function_with_object_method_that_does_not_return_number
|
301
|
-
@rule.rule = '
|
302
|
-
|
303
|
-
|
304
|
-
|
301
|
+
@rule.rule = 'average(:methods) == 0'
|
302
|
+
assert @rule.match(get_things([1, 2]))
|
303
|
+
@rule.rule = 'sum(:methods) == 0'
|
304
|
+
assert @rule.match(get_things([1, 2]))
|
305
|
+
@rule.rule = 'count(:methods) == 2'
|
306
|
+
assert @rule.match(get_things([1, 2]))
|
305
307
|
end
|
306
308
|
|
307
309
|
def test_match_without_rule
|
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.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Allow a user to define a set of rules, and then test to see if an array
|
15
15
|
of object match those rules.
|