philter 0.7.0 → 1.0.0

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.
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