philter 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -1
  3. data/README.md +126 -26
  4. data/lib/array.rb +24 -33
  5. data/lib/base.rb +166 -102
  6. data/lib/version.rb +1 -1
  7. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8951ec753df7fa132093b21a0a8009a9c329d9cb
4
- data.tar.gz: 07984bed1282a70c5de687efd3437cec0aea6253
3
+ metadata.gz: 752a73c7c043fd49ebb875fca66209e6865b1f17
4
+ data.tar.gz: 2c010a42446deff32ac4edc8bb2a0934333f8910
5
5
  SHA512:
6
- metadata.gz: 6433fb9f2a1834a1338bf35eac6212abbda14fa56e6c82eb3e8ece0a5a2bcbb8eab677e563151efe3486435745b2478b1e8910c6bc0de27af1d91a9bc1189e48
7
- data.tar.gz: 668b8cf92c6e6267a98c96c916c01ee49fc82f4f50f357d42d03eaa3a075ac8fe6f10eed420d81c59f9cdfd414846d7fefc0595554c72e085a16e3f6f6d09513
6
+ metadata.gz: db08c41adc22da507100dba892ed3329a0d2e6e7a352cd459408ad30cb078fafd06988d228c646a111d2cdd4e606e9e80591b8445611d53f9b1026b88b96e506
7
+ data.tar.gz: 4449e25ad6b6a348d15edb3ae3292b16bb95eef9f52749598a1cfc486f613a6186decc62a481c8bd9d28da1a55e321bad169cde3ff15bed5492844ce9334d24f
@@ -1,4 +1,33 @@
1
- v0.7.0 [☰](https://github.com/marcomd/Philter/compare/v0.7.0...v0.6.0) May 24th, 2016
1
+ v1.0.0 [☰](https://github.com/marcomd/Philter/compare/v0.8.0...v1.0.0) May 25th, 2016
2
+ ------------------------------
3
+ * Code revolution: more simple, secure and readable
4
+ * Performance: now it use grep for simple search
5
+ * Test:
6
+ * wide coverage with 37 unit tests and 137 assertions
7
+ * updated 8 performance tests
8
+ * Functional:
9
+ * now you can pass a block to update or completely change any array's element
10
+ * you can search multiple attributes with and boolean operator. It's also possible use `or` as option
11
+ * added option `everywhere` to search an attribute also in simple value.
12
+ Examples:
13
+ ```ruby
14
+ [:first, :second, {id: 1, tag: :first}, {id: 2, tag: :second}].philter tag: :first
15
+ => [{:id=>1, :tag=>:first}]
16
+ [:first, :second, {id: 1, tag: :first}, {id: 2, tag: :second}].philter({tag: :first}, everywhere: true)
17
+ => [:first, {:id=>1, :tag=>:first}]
18
+ ```
19
+
20
+
21
+ v0.8.0 May 24th, 2016
22
+ ------------------------------
23
+ * Added philter by class, example:
24
+ ```ruby
25
+ [:first, 'second'].philter Symbol
26
+ => [:first]
27
+ ```
28
+ * Many internal changement
29
+
30
+ v0.7.0 [☰](https://github.com/marcomd/Philter/compare/v0.6.0...v0.7.0) May 24th, 2016
2
31
  ------------------------------
3
32
  * Added performance tests
4
33
 
data/README.md CHANGED
@@ -36,6 +36,10 @@ require 'philter'
36
36
  %w[red green blue].philter %w(red blue)
37
37
  => ["red", "blue"]
38
38
 
39
+ # You can pass a block
40
+ [1,2,3].philter([1,2]){|e|e*2}
41
+ => [2, 4]
42
+
39
43
  # Array of hashes
40
44
  [
41
45
  {id: 1, name: 'Mark' },
@@ -72,6 +76,39 @@ require 'philter'
72
76
  {id: 3, name: 'Bill', email: 'bill@live.com' }
73
77
  ].philter({email: /@gmail/}, get: :name)
74
78
  => ["Mark", "Larry"]
79
+
80
+ # Philter with more attributes
81
+ [
82
+ {id: 1, name: 'Mark', email: 'mark@gmail.com' },
83
+ {id: 2, name: 'Larry', email: 'larry@gmail.com' },
84
+ {id: 3, name: 'Bill', email: 'bill@live.com' }
85
+ ].philter name: /M.+/, email: /@gmail/
86
+ => [{:id=>1, :name=>"Mark", :email=>"mark@gmail.com"}]
87
+
88
+ # Philter with an attribute or another
89
+ [
90
+ {id: 1, name: 'Mark', email: 'mark@gmail.com' },
91
+ {id: 2, name: 'Larry', email: 'larry@gmail.com' },
92
+ {id: 3, name: 'Bill', email: 'bill@live.com' }
93
+ ].philter({name: /M.+/, email: /@live/}, or: true)
94
+ => [{:id=>1, :name=>"Mark", :email=>"mark@gmail.com"}, {:id=>3, :name=>"Bill", :email=>"bill@live.com"}]
95
+
96
+ # A bit of magic
97
+ # Select and update attributes
98
+ [
99
+ {id: 1, name: 'Mark', email: 'mark@gmail.com' },
100
+ {id: 2, name: 'Larry', email: 'larry@gmail.com' },
101
+ {id: 3, name: 'Bill', email: 'bill@live.com' }
102
+ ].philter({email: /@gmail/}){|e| e[:name] << ' use gmail!'}
103
+ => ["Mark use gmail!", "Larry use gmail!"]
104
+
105
+ # Add attributes
106
+ [
107
+ {id: 1, name: 'Mark', email: 'mark@gmail.com' },
108
+ {id: 2, name: 'Larry', email: 'larry@gmail.com' },
109
+ {id: 3, name: 'Bill', email: 'bill@live.com' }
110
+ ].philter({email: /@gmail/}){|e| e[:surname] = 'unknown';e }
111
+ => :try_yourself
75
112
  ```
76
113
 
77
114
  Get the trace with the option `debug: true`
@@ -115,31 +152,73 @@ cities.philter id: 1
115
152
  cities.philter code: 'PA'
116
153
  => [#<City id: 4, name: "Palermo", code: "PA", region: "Sicilia", created_at: "2016-05-10 09:08:13", updated_at: "2016-05-10 09:08:13">]
117
154
 
118
- cities.philter(region: /\Alomb/i).size
119
- => 4
155
+ # Pass a block to select, update or change the result
156
+ cities.philter(region: /\Alomb/i){|city| "#{city.name}-#{city.code}"}
157
+ => ["Milano-MI", "Lecco-LC", "Pavia-PV", "Piacenza-PC"]
158
+
120
159
  ```
121
160
 
122
161
  ## Performance
123
162
 
124
- If you need a lot of speed it would be better to use grep when you can or select manually your items.
163
+ Since version `1.0.0` performance are greatly improved!
164
+ Ruby 2.2.3p173 on windows 7 with i5 3570K Ivy Bridge @4200 Mhz Ram 16Gb 10-10-10-27 2T @686Mhz
125
165
 
126
166
  ```ruby
127
167
  require 'benchmark'
168
+ require 'philter'
128
169
 
129
170
  ar_test = 100.times.map{|n| n}
130
171
  Benchmark.bmbm do |x|
131
- x.report("philter: ") { 1_000.times { ar_test.philter [1,2] } }
132
- x.report("grep: ") { 1_000.times { ar_test.grep [1,2] } }
172
+ x.report("philter: ") { 10_000.times { ar_test.philter 1 } }
173
+ x.report("grep: ") { 10_000.times { ar_test.grep 1 } }
133
174
  end
134
175
 
135
- Rehearsal ---------------------------------------------
136
- philter: 1.872000 0.000000 1.872000 ( 1.859130)
137
- grep: 0.031000 0.000000 0.031000 ( 0.017170)
138
- ------------------------------------ total: 1.903000sec
176
+ #version 1.0.0
177
+ user system total real
178
+ philter: 0.031000 0.000000 0.031000 ( 0.021759)
179
+ grep: 0.016000 0.000000 0.016000 ( 0.007115)
139
180
 
181
+ #version 0.7.0
140
182
  user system total real
141
- philter: 1.826000 0.000000 1.826000 ( 1.834825)
142
- grep: 0.016000 0.000000 0.016000 ( 0.016777)
183
+ philter: 9.204000 0.000000 9.204000 ( 9.254443)
184
+ grep: 0.062000 0.000000 0.062000 ( 0.054257)
185
+ ```
186
+
187
+ ```ruby
188
+ range = 1..10
189
+ Benchmark.bmbm do |x|
190
+ x.report("philter: ") { 10_000.times { ar_test.philter range } }
191
+ x.report("grep: ") { 10_000.times { ar_test.grep range } }
192
+ end
193
+
194
+ #version 1.0.0
195
+ user system total real
196
+ philter: 0.015000 0.000000 0.015000 ( 0.023891)
197
+ grep: 0.000000 0.000000 0.000000 ( 0.009134)
198
+
199
+ #version 0.7.0
200
+ => Range was not managed
201
+ user system total real
202
+ philter: 91.136000 0.000000 91.136000 ( 91.305855)
203
+ grep: 0.172000 0.000000 0.172000 ( 0.182490)
204
+ ```
205
+
206
+ ```ruby
207
+ ar_search = [1,3,5,7]
208
+ Benchmark.bmbm do |x|
209
+ x.report("philter: ") { 10_000.times { ar_test.philter ar_search } }
210
+ x.report("select: ") { 10_000.times { ar_test.select{|item| ar_search.include? item } } }
211
+ end
212
+
213
+ #version 1.0.0
214
+ user system total real
215
+ philter: 0.062000 0.000000 0.062000 ( 0.052933)
216
+ select: 0.031000 0.000000 0.031000 ( 0.022178)
217
+
218
+ #version 0.7.0
219
+ user system total real
220
+ philter: 36.176000 0.000000 36.176000 ( 36.182101)
221
+ select: 0.078000 0.000000 0.078000 ( 0.073341)
143
222
  ```
144
223
 
145
224
  ```ruby
@@ -148,31 +227,33 @@ Benchmark.bmbm do |x|
148
227
  x.report("select: ") { 1_000.times { ar_test.select {|item| item < 50} } }
149
228
  end
150
229
 
151
- Rehearsal ---------------------------------------------
152
- philter: 3.775000 0.000000 3.775000 ( 3.779718)
153
- select: 0.000000 0.000000 0.000000 ( 0.004455)
154
- ------------------------------------ total: 3.775000sec
230
+ #version 1.0.0
231
+ user system total real
232
+ philter: 2.855000 0.000000 2.855000 ( 2.851040)
233
+ select: 0.015000 0.000000 0.015000 ( 0.004312)
155
234
 
235
+ #version 0.7.0
156
236
  user system total real
157
237
  philter: 3.744000 0.000000 3.744000 ( 3.746851)
158
238
  select: 0.016000 0.000000 0.016000 ( 0.004338)
159
239
  ```
160
240
 
161
241
  ```ruby
162
- ar_test = [ {id: 1, name: 'Mark', email: 'mark@gmail.com'},
163
- {id: 2, name: 'Bill', email: 'bill@live.com'},
164
- {id: 3, name: 'Larry', email: 'larry@gmail.com'}]
242
+ ar_test = [ {id: 1, name: 'Mark', email: 'mark@gmail.com' },
243
+ {id: 2, name: 'Bill', email: 'bill@live.com' },
244
+ {id: 3, name: 'Larry', email: 'larry@gmail.com' }]
165
245
  regexp = /\A.+gmail/
166
246
  Benchmark.bmbm do |x|
167
247
  x.report("philter: ") { 10_000.times { ar_test.philter email: regexp } }
168
248
  x.report("select: ") { 10_000.times { ar_test.select {|item| item[:email] =~ regexp} } }
169
249
  end
170
250
 
171
- Rehearsal ---------------------------------------------
172
- philter: 0.515000 0.000000 0.515000 ( 0.490562)
173
- select: 0.000000 0.000000 0.000000 ( 0.003961)
174
- ------------------------------------ total: 0.515000sec
251
+ #version 1.0.0
252
+ user system total real
253
+ philter: 0.218000 0.000000 0.218000 ( 0.221822)
254
+ select: 0.000000 0.000000 0.000000 ( 0.003418)
175
255
 
256
+ #version 0.7.0
176
257
  user system total real
177
258
  philter: 0.468000 0.000000 0.468000 ( 0.473782)
178
259
  select: 0.000000 0.000000 0.000000 ( 0.003429)
@@ -186,12 +267,14 @@ Ruby `1.9+`
186
267
 
187
268
  gem install philter
188
269
 
189
- To use it in a rails project, add to gem file `gem 'philter'` and run `bundle install`
270
+ To use it in a bundle, add to gem file `gem 'philter'` and run `bundle install`
190
271
 
191
272
  ## To Do
192
273
 
193
- * Add boolean operator to chain of conditions
194
- * Improve performance keeping the operations's trace
274
+ - [x] Add boolean operator to chain of conditions `v1.0.0`
275
+ - [x] Improve performance keeping the operations's trace `v1.0.0`
276
+ - [x] Add block `v1.0.0`
277
+ - [ ] Increase performance further
195
278
 
196
279
  ## Contributing
197
280
 
@@ -203,6 +286,8 @@ To use it in a rails project, add to gem file `gem 'philter'` and run `bundle in
203
286
 
204
287
  ## Testing
205
288
 
289
+ Wide coverage with `37 unit tests` and `137 assertions`
290
+
206
291
  To test locally install the development requirements
207
292
 
208
293
  bundle install
@@ -215,7 +300,22 @@ Performance tests are calibrated to not exceed 1.2 seconds on my pc with a toler
215
300
 
216
301
  bundle exec ruby test\performance_test.rb
217
302
 
218
- If you have a very slow pc it could not pass. In this case you can pass as an argument a higher tolerance value, for example 3 seconds:
303
+ ```
304
+ Loaded suite test/performance_test
305
+ Started
306
+ ........
307
+
308
+ Finished in 8.505 seconds.
309
+ --------------------------------------------------------------------------------
310
+
311
+ 8 tests, 8 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
312
+ 100% passed
313
+ --------------------------------------------------------------------------------
314
+
315
+ 0.94 tests/s, 0.94 assertions/s
316
+ ```
317
+
318
+ If you have a very slow pc it could not pass. In this case you can pass a higher tolerance value as argument, for example 3 seconds:
219
319
 
220
320
  bundle exec ruby test\performance_test.rb 3.0
221
321
 
@@ -1,6 +1,6 @@
1
1
  class Array
2
2
  include Philter::Base
3
- def philter search=nil, options={}
3
+ def philter search=nil, options={}, &block
4
4
  options = {
5
5
  get: nil,
6
6
  debug: false
@@ -9,41 +9,32 @@ class Array
9
9
  puts philter_help if options[:debug]
10
10
  raise "Specify search parameter!"
11
11
  end
12
- results = []
13
- self.each do |item|
14
- puts "item #{item.class.name} #{item}" if options[:debug]
15
- if search.respond_to? :each
16
- # search: {} or []
17
- selected = phil_search_from_list search, item, options
18
- elsif search.is_a?(Regexp)
19
- # Search has one item
20
- # search: 3 or search: 'a'
21
- print " b. " if options[:debug]
22
- selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '=~')
23
- puts " #{'=> X' if selected}" if options[:debug]
12
+
13
+ apply_block = true
14
+ results =
15
+ case search.class.name
16
+ when "Hash"
17
+ print " h. " if options[:debug]
18
+ phil_search_by_attributes search, options
19
+ when "String"
20
+ print " s. " if options[:debug]
21
+ operator = phil_get_operator search
22
+ operator ? phil_search_with_operator(search, operator: operator) : self.grep(search)
23
+ when "Array"
24
+ print " a. " if options[:debug]
25
+ phil_search_by_array search, options
24
26
  else
25
- # Search has one item
26
- # search: 3 or search: 'a'
27
- # search: '<3' or any other operator
28
- print " c. " if options[:debug]
29
- selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '==')
30
- puts " #{'=> X' if selected}" if options[:debug]
31
- end
32
- if selected
33
- results <<
34
- if options[:get]
35
- if item.respond_to? options[:get]
36
- item.send options[:get]
37
- elsif item.respond_to? '[]'
38
- item[options[:get]]
39
- end
40
- else
41
- item
42
- end
43
- end
27
+ puts " g. #{search}" if options[:debug]
28
+ apply_block = false
29
+ self.grep(search, &block)
44
30
  end
31
+
45
32
  puts "------------------" if options[:debug]
46
33
  puts " #{results ? results.size : 'No'} item#{results && results.size == 1 ? '' : 's'} found" if options[:debug]
47
- results
34
+ if block_given? && apply_block
35
+ results.map{|item| block.call(item)}
36
+ else
37
+ results
38
+ end
48
39
  end
49
40
  end
@@ -1,127 +1,191 @@
1
1
  module Philter
2
2
  module Base
3
3
  private
4
- def philter_help
5
- <<-HELP.gsub(/^ /, '')
6
- *************************************************************************
7
- Philter version #{Philter.version}
8
- [].philter 'search', {options}
9
- Examples:
10
- [1,2,3].philter 1 => [1]
11
- [1,2,3].philter [2,3] => [2, 3]
12
- [{id: 1, name: 'Mark'},{id: 2, name: 'Bill'}].philter id: 1
13
- Articles.philter id: 1
14
- People.philter name: 'Mario'
15
- People.philter email: /\A.+@gmail/
16
- Use option get: to select an attribute
17
- People.philter {id: 1}, get: :surname
18
- Use option debug: to watch the selection
19
- Articles.philter {id: 1}, debug: true
20
- *************************************************************************
21
- HELP
4
+
5
+ def phil_search_with_operator search, options={}
6
+ results = []
7
+ self.each do |item|
8
+ puts "item #{item.class.name} #{item}" if options[:debug]
9
+ selected = phil_evaluate item, search, options
10
+ puts " #{'=> X' if selected}" if options[:debug]
11
+ results << item if selected
12
+ end
13
+ results
22
14
  end
23
15
 
24
- def get_operator exp
25
- return unless exp.is_a? String
26
- regexp = "(?:<=?|>=?|!=|==|===|=~)"
27
- if exp =~ /#{regexp}/
28
- exp.match(/#{regexp}/).to_s
16
+ def phil_search_by_array search, options={}
17
+ puts "search #{search} (#{search.class.name}) " if options[:debug]
18
+ search_same_class = false
19
+ search.inject{|prev, cur| search_same_class=prev.class == cur.class; cur }
20
+ if search_same_class
21
+ self.select do |item|
22
+ if search.first.class.name == 'Class'
23
+ search.include? item.class
24
+ else
25
+ search.include? item
26
+ end
27
+ end
29
28
  else
30
- nil
29
+ # Check every search item
30
+ search.each do |search_value|
31
+ self.select do |item|
32
+ if search_value.class.name == 'Class'
33
+ search_value == item.class
34
+ else
35
+ search_value == item
36
+ end
37
+ end
38
+ end
31
39
  end
32
40
  end
33
41
 
34
- def phil_evaluate item, label, value, evaluation, options={}
35
- options = {
36
- operator: '==',
37
- debug: false
38
- }.merge(options)
39
- operator = get_operator value
40
- value = operator ? value.gsub(operator,'').to_i : value
41
- operator ||= options[:operator]
42
- item_to_s = operator == '=~' ? '.to_s' : ''
43
- case evaluation
44
- when :method
45
- print " #{item.class.name}.#{label} #{operator} value " if options[:debug]
46
- print "| #{item.send(label)} #{operator} #{value}" if options[:debug]
47
- eval("item.send(label) #{operator} value")
48
- when :hash
49
- print " #{item.class.name}[:#{label}] #{operator} value" if options[:debug]
50
- print "| #{item[label]} #{operator} #{value} " if options[:debug]
51
- eval("item[label]#{item_to_s} #{operator} value")
52
- when :simple
53
- print " item #{operator} value" if options[:debug]
54
- print " | #{item} #{operator} #{value}" if options[:debug]
55
- eval("item#{item_to_s} #{operator} value")
56
- else
57
- raise "phil_evaluate: evaluation #{evaluation ? "#{evaluation} not valid!" : "blank!"}"
42
+ def phil_search_by_attributes search, options={}
43
+ results = []
44
+ self.each do |item|
45
+ selected = nil
46
+ # Evaluate each array's item
47
+ puts "item #{item} (#{item.class.name}) " if options[:debug]
48
+ case item.class.name
49
+ when "Array"
50
+ print " a. discarded" if options[:debug]
51
+ when "Hash"
52
+ print " h. " if options[:debug]
53
+ selected = phil_apply_attributes item, search, options
54
+ when phil_base_objects
55
+ print " b. discarded" if options[:debug]
56
+ else
57
+ print " o. " if options[:debug]
58
+ selected = phil_apply_attributes item, search, options
59
+ end
60
+ # puts " #{'=> X' if selected}" if options[:debug]
61
+ if selected
62
+ results <<
63
+ if options[:get]
64
+ if item.respond_to? options[:get]
65
+ item.send options[:get]
66
+ elsif item.respond_to? '[]'
67
+ item[options[:get]]
68
+ end
69
+ else
70
+ item
71
+ end
72
+ end
58
73
  end
74
+ results
59
75
  end
60
76
 
61
- # Search params respond to each method
62
- def phil_search_from_list search, item, options={}
63
- selected_or, selected_and = nil, nil
64
- search.each do |value|
77
+ def phil_apply_attributes item, search, options={}
78
+ selected_or, selected_and = nil, true
79
+ search.each do |key, search_value|
65
80
  # Every item must match with search options to be selected
66
- puts " a. search: #{value.class.name} #{value}" if options[:debug]
67
- if value.is_a?(Array)
68
- # Example search: {code: 1} or search: {code: [1,2]}
69
- label, values = value
70
- values = [values] unless values.is_a?(Array)
71
- values.each do |value|
72
- selected = phil_search_is_array label, value, item, options
73
- selected_or = true if !selected_or && selected
74
- selected_and = selected if selected_and
75
- end
76
- elsif value.is_a?(Regexp)
77
- # search: {email: /@gmail/}
78
- print " 2. " if options[:debug]
79
- selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '=~')
80
- puts " #{'=> X' if selected}" if options[:debug]
81
- else
82
- # Example search: [3] or search: [3, 4]
83
- print " 3. " if options[:debug]
84
- selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '==')
85
- puts " #{'=> X' if selected}" if options[:debug]
81
+ puts " search: #{key}: #{search_value} (#{search_value.class.name})" if options[:debug]
82
+ case search_value.class.name
83
+ when 'Regexp'
84
+ # search: {email: /@gmail/}
85
+ print " .1 " if options[:debug]
86
+ selected = phil_evaluate item_value(item, key, options), search_value, options.merge(operator: '=~')
87
+ when 'Class'
88
+ # search: {code: String} or {code: Fixnum}
89
+ print " .2 item.class == value | #{item.class} == #{search_value}" if options[:debug]
90
+ selected = item_value(item, key, options).class == search_value
91
+ when 'Array'
92
+ # search: {id: [1,2]}
93
+ print " .3 " if options[:debug]
94
+ selected = search_value.include? item_value(item, key, options)
95
+ else
96
+ # search: {id: 2} or {id: '<3'} or any other operator
97
+ print " .4 " if options[:debug]
98
+ selected = phil_evaluate item_value(item, key, options), search_value, options.merge(operator: '==')
86
99
  end
100
+ puts " #{'=> x' if selected}" if options[:debug]
87
101
  selected_or = true if !selected_or && selected
88
102
  selected_and = selected if selected_and
89
103
  end
90
- selected_or
104
+
105
+ if options[:or]
106
+ puts " #{'=> X (Or)' if selected_or}" if options[:debug]
107
+ selected_or
108
+ else
109
+ puts " #{'=> X (And)' if selected_and}" if options[:debug]
110
+ selected_and
111
+ end
91
112
  end
92
113
 
93
- def phil_search_is_array label, value, item, options={}
94
- selected = nil
95
- if item.respond_to?(label)
96
- print " 1.x " if options[:debug]
97
- if value.is_a?(Regexp)
98
- print " .1 " if options[:debug]
99
- selected = phil_evaluate item, label, value, :method, options.merge(operator: '=~')
100
- else
101
- # search: {id: 2}
102
- # search: {id: '<3'} or any other operator
103
- print " .2 " if options[:debug]
104
- selected = phil_evaluate item, label, value, :method, options.merge(operator: '==')
105
- end
106
- elsif item.respond_to? '[]'
107
- print " 1.y label: #{label.class.name}" if options[:debug]
108
- if value.is_a?(Regexp)
109
- # search: {email: /@gmail/}
110
- print " .1 " if options[:debug]
111
- selected = phil_evaluate item, label, value, :hash, options.merge(operator: '=~')
112
- elsif item.is_a?(Hash) && !label.is_a?(Fixnum)
113
- # search: {id: 1} or {'name' => 'Mark'}
114
- # search: {id: '<3'} or any other operator
115
- print " .2 " if options[:debug]
116
- selected = phil_evaluate item, label, value, :hash, options.merge(operator: '==')
114
+ def item_value item, label, options={}
115
+ case item.class.name
116
+ when "Hash" then
117
+ print " v1 item[#{label}] " if options[:debug]
118
+ item[label]
119
+ when "Fixnum", "Float", "Bignum", "Symbol", "String"
120
+ print " v2 #{item.class.name} " if options[:debug]
121
+ if options[:everywhere]
122
+ print "#{item} " if options[:debug]
123
+ item
124
+ else
125
+ print "- " if options[:debug]
126
+ nil
127
+ end
117
128
  else
118
- print " .3 no action for #{value} !!!" if options[:debug]
119
- end
129
+ print " v3 item.#{label} " if options[:debug]
130
+ item.send(label) if item.respond_to? label
131
+ end
132
+ end
133
+
134
+ def phil_evaluate item, value, options={}
135
+ options = {
136
+ operator: '==',
137
+ debug: false
138
+ }.merge(options)
139
+ operator = phil_get_operator value
140
+ value = operator ? value.gsub(operator,'').to_i : value
141
+ operator ||= options[:operator]
142
+ print " item #{operator} value" if options[:debug]
143
+ print " | #{item} #{operator} #{value}" if options[:debug]
144
+ case operator
145
+ when '=~' then item.to_s =~ value
146
+ when '==' then item == value
147
+ when '===' then item === value
148
+ when '>' then item > value
149
+ when '<' then item < value
150
+ when '>=' then item >= value
151
+ when '<=' then item <= value
152
+ when '!=' then item != value
153
+ end
154
+ end
155
+
156
+ def phil_get_operator exp
157
+ return unless exp.is_a? String
158
+ regexp = "(?:<=?|>=?|!=|==|===|=~)"
159
+ if exp =~ /#{regexp}/
160
+ exp.match(/#{regexp}/).to_s
120
161
  else
121
- print " 1.z selector not present !!!" if options[:debug]
162
+ nil
122
163
  end
123
- puts " #{'=> X' if selected}" if options[:debug]
124
- selected
125
164
  end
165
+
166
+ def phil_base_objects
167
+ return "Fixnum", "Float", "Bignum", "Symbol", "String"
168
+ end
169
+
170
+ def philter_help
171
+ <<-HELP.gsub(/^ /, '')
172
+ *************************************************************************
173
+ Philter version #{Philter.version}
174
+ [].philter 'search', {options}
175
+ Examples:
176
+ [1,2,3].philter 1 => [1]
177
+ [1,2,3].philter [2,3] => [2, 3]
178
+ [{id: 1, name: 'Mark'},{id: 2, name: 'Bill'}].philter id: 1
179
+ Articles.philter id: 1
180
+ People.philter name: 'Mario'
181
+ People.philter email: /\A.+@gmail/
182
+ Use option get: to select an attribute
183
+ People.philter {id: 1}, get: :surname
184
+ Use option debug: to watch the selection
185
+ Articles.philter {id: 1}, debug: true
186
+ *************************************************************************
187
+ HELP
188
+ end
189
+
126
190
  end
127
191
  end
@@ -1,5 +1,5 @@
1
1
  module Philter
2
2
  def self.version
3
- "0.7.0"
3
+ "1.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Mastrodonato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-24 00:00:00.000000000 Z
11
+ date: 2016-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit