filter 0.0.4 → 0.0.5

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/filter.rb CHANGED
@@ -1,3 +1,7 @@
1
+ require "filter/condition"
2
+ require "filter/or"
3
+ require "filter/and"
4
+
1
5
  # == Synopsys
2
6
  # Extension for Ruby <code>Enumerable</code> module
3
7
  #
@@ -33,47 +37,12 @@ module Enumerable
33
37
 
34
38
  # move +block+ to +patterns+ if no +patterns+ given
35
39
  patterns, block = [block], nil if block_given? && patterns.empty?
36
- conditions = patterns.map { |pattern| filter_condition(pattern) }
37
-
38
40
  # match elements against all patterns using +OR+ operator
39
- filtered = select do |obj|
40
- conditions.any? { |condition| condition.call(obj) }
41
- end
41
+ conditions = Filter.or(*patterns)
42
+
43
+ filtered = select { |obj| conditions === obj }
42
44
 
43
45
  # also transform elements if block given
44
46
  block ? filtered.map(&block) : filtered
45
47
  end
46
-
47
- private
48
- def filter_condition(pattern) #:nodoc:
49
- # create filter condition from pattern
50
- case pattern
51
- when NilClass then proc { true }
52
-
53
- when Class, Module then
54
- proc do |e|
55
- e.is_a?(Class) || e.is_a?(Module) ?
56
- e <= pattern :
57
- e.is_a?(pattern)
58
- end
59
-
60
- when Symbol, Proc, Method then pattern.to_proc
61
-
62
- when Array then # enum.filter [:even?, :positive?, :cool?, proc { |n| n < 10 }]
63
- proc do |e|
64
- pattern.all? { |condition| filter_condition(condition).call(e) }
65
- end
66
-
67
- when Hash then # enum.filter :to_i => :even?, :ceil => :odd?
68
- proc do |e|
69
- pattern.all? do |attribute, condition|
70
- filter_condition(condition).call(attribute.to_proc.call(e))
71
- end
72
- end
73
-
74
- when TrueClass, FalseClass then proc { |e| !!e == pattern }
75
-
76
- else proc { |e| pattern === e } # otherwise - String, Regexp, Numeric etc.
77
- end
78
- end
79
48
  end
data/lib/filter/and.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "filter/condition"
2
+
3
+ module Filter
4
+ class And < Condition
5
+ def initialize(*patterns)
6
+ @matchers = patterns.map { |pattern| Matcher.new(pattern) }
7
+ end
8
+
9
+ def ===(other)
10
+ @matchers.all? { |m| m === other }
11
+ end
12
+ end
13
+
14
+ def and(*patterns)
15
+ And.new(*patterns)
16
+ end
17
+ module_function :and
18
+ end
@@ -0,0 +1,23 @@
1
+ require "filter/matcher"
2
+
3
+ module Filter
4
+ class Condition
5
+ def initialize(pattern)
6
+ @matcher = Filter::Matcher.new(pattern)
7
+ end
8
+
9
+ def ===(another)
10
+ @matcher === another
11
+ end
12
+
13
+ def and(other)
14
+ Filter.and(self, other)
15
+ end
16
+ alias & and
17
+
18
+ def or(other)
19
+ Filter.or(self, other)
20
+ end
21
+ alias | or
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ require "filter/matchers/base"
2
+ require "filter/matchers/array"
3
+ require "filter/matchers/boolean"
4
+ require "filter/matchers/class"
5
+ require "filter/matchers/hash"
6
+ require "filter/matchers/nil"
7
+ require "filter/matchers/symbol"
8
+
9
+ module Filter
10
+ module Matcher
11
+ MAPPING = {
12
+ [NilClass] => Filter::Matchers::Nil,
13
+ [TrueClass, FalseClass] => Filter::Matchers::Boolean,
14
+ [Class, Module] => Filter::Matchers::Class,
15
+ [Array] => Filter::Matchers::Array,
16
+ [Symbol, Proc, Method, UnboundMethod] => Filter::Matchers::Symbol,
17
+ [Hash] => Filter::Matchers::Hash,
18
+ }
19
+
20
+ def new(pattern)
21
+ klass = nil
22
+
23
+ MAPPING.each_pair do |classes, matcher_klass|
24
+ klass = matcher_klass if classes.any? { |cls| pattern.is_a?(cls) }
25
+ end
26
+
27
+ klass = Filter::Matchers::Base if klass.nil?
28
+
29
+ klass.new(pattern)
30
+ end
31
+ module_function :new
32
+ end
33
+
34
+ def match(pattern)
35
+ Matcher.new(pattern)
36
+ end
37
+ module_function :match
38
+ end
@@ -0,0 +1,13 @@
1
+ module Filter
2
+ module Matchers
3
+ class Array < Base
4
+ def initialize(pattern)
5
+ @pattern = pattern.map(&:to_proc)
6
+ end
7
+
8
+ def ===(other)
9
+ pattern.all? { |p| p === other }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module Filter
2
+ module Matchers
3
+ class Base
4
+ attr_reader :pattern
5
+
6
+ def initialize(pattern)
7
+ @pattern = pattern
8
+ end
9
+
10
+ def ===(other)
11
+ pattern === other
12
+ end
13
+
14
+ def and(other)
15
+ Filter.and(self, other)
16
+ end
17
+ alias & and
18
+
19
+ def or(other)
20
+ Filter.or(self, other)
21
+ end
22
+ alias | or
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ module Filter
2
+ module Matchers
3
+ class Boolean < Base
4
+ def ===(other)
5
+ !!other == pattern
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Filter
2
+ module Matchers
3
+ class Class < Base
4
+ def ===(other)
5
+ other.is_a?(::Class) || other.is_a?(::Module) ?
6
+ other <= pattern :
7
+ other.is_a?(pattern)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Filter
2
+ module Matchers
3
+ class Hash < Base
4
+ def initialize(pattern)
5
+ @pattern = ::Hash[pattern.map { |k, v| [k.to_proc, Filter::Matcher.new(v)]}]
6
+ end
7
+
8
+ def ===(other)
9
+ pattern.all? do |attr, pattern|
10
+ pattern === attr.call(other)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module Filter
2
+ module Matchers
3
+ class Nil < Base
4
+ # nil condition always results to true
5
+ def ===(other)
6
+ true
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module Filter
2
+ module Matchers
3
+ class Symbol < Base
4
+ def initialize(pattern)
5
+ @pattern = pattern.to_proc
6
+ end
7
+
8
+ def ===(other)
9
+ pattern.call(other)
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/filter/or.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "filter/condition"
2
+
3
+ module Filter
4
+ class Or < Condition
5
+ def initialize(*patterns)
6
+ @matchers = patterns.map { |pattern| Matcher.new(pattern) }
7
+ end
8
+
9
+ def ===(other)
10
+ @matchers.any? { |m| m === other }
11
+ end
12
+ end
13
+
14
+ def or(*patterns)
15
+ Or.new(*patterns)
16
+ end
17
+ module_function :or
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Filter
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/spec/filter_spec.rb CHANGED
@@ -57,4 +57,14 @@ describe Enumerable do
57
57
  it "should match using OR operator" do
58
58
  [0, 2, 3, 4].filter(:zero?, :odd?).should == [0, 3]
59
59
  end
60
+
61
+ it "should be flexible" do
62
+ conditions = Filter.match(:even?) | :odd? | :zero?
63
+
64
+ [0, 1, 2].filter(conditions).should == [0, 1, 2]
65
+
66
+ # 0 and negative
67
+ conditions = Filter.and(:zero?, :even?) | proc { |n| n < 0 }
68
+ [-1, 0, 1].filter(conditions).should == [-1, 0]
69
+ end
60
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-12-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &20615240 !ruby/object:Gem::Requirement
16
+ requirement: &13830380 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *20615240
24
+ version_requirements: *13830380
25
25
  description: ! "== Synopsys\n<code>Enumerable#filter</code> - extended <code>Enumerable#select</code>\n\n==
26
26
  Examples\nString filter (acts like <code>Enumerable#grep</code>):\n [1, 2, 3, 'ab'].filter(/a/)
27
27
  \ # => ['ab']\n [1, 2, 3, '3'].filter('3') # => ['3']\n\nYou
@@ -50,6 +50,17 @@ files:
50
50
  - Rakefile
51
51
  - filter.gemspec
52
52
  - lib/filter.rb
53
+ - lib/filter/and.rb
54
+ - lib/filter/condition.rb
55
+ - lib/filter/matcher.rb
56
+ - lib/filter/matchers/array.rb
57
+ - lib/filter/matchers/base.rb
58
+ - lib/filter/matchers/boolean.rb
59
+ - lib/filter/matchers/class.rb
60
+ - lib/filter/matchers/hash.rb
61
+ - lib/filter/matchers/nil.rb
62
+ - lib/filter/matchers/symbol.rb
63
+ - lib/filter/or.rb
53
64
  - lib/filter/version.rb
54
65
  - spec/filter_spec.rb
55
66
  - spec/test_helper.rb