filter 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ group :development do
5
+ gem 'rspec'
6
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Alexey Mikhaylov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ == Synopsys
2
+ Enumerable#filter - extended Enumerable#select
3
+
4
+ == Examples
5
+ String filter (acts like Enumerable#grep):
6
+ [1, 2, 3, 'ab'].filter(/a/) # => #<Enumerator: ['ab']>
7
+ [1, 2, 3, '3'].filter('3') # => #<Enumerator: ['3']>
8
+
9
+ You can pass a <tt>Proc</tt> or <tt>Symbol</tt>. Methods and blocks are allowed too:
10
+ [1, 2, 3].filter(&:even?) # => #<Enumerator: [2]>
11
+ [1, 2, 3].filter(:even?) # => #<Enumerator: [2]>
12
+ [1, 2, 4].filter { |num| num.even? } # => #<Enumerator: [2, 4]>
13
+
14
+ <tt>Enumerable#filter</tt> can match against enumerable items attributes. Like this:
15
+ [1, 2, 3, 4.2].filter :to_i => :even? # => #<Enumerator: [2, 4]>
16
+
17
+ If the block is supplied, each matching element is passed to it, and the block’s result is stored in the output enumerator.
18
+ [1, 2, 4].filter(&:even?) { |n| n + 1 } # => #<Enumerator: [3, 5]>
19
+
20
+ <tt>Enumerable#filter</tt> also accepts <tt>true</tt> or <tt>false</tt> as argument:
21
+ [0, false, 2, nil].filter(true) # => #<Enumerator: [0, 2]>
22
+ [0, false, 2, nil].filter(false) # => #<Enumerator: [false, nil]>
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/filter.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "filter/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "filter"
8
+ s.version = Filter::VERSION
9
+ s.authors = ["Alexey Mikhaylov"]
10
+ s.email = ["amikhailov83@gmail.com"]
11
+ s.homepage = "https://github.com/take-five/filter"
12
+ s.summary = %q{Enumerable#filter - extended Enumerable#select combined with Enumerable#collect}
13
+ s.description = File.read(File.expand_path('../README.rdoc', __FILE__))
14
+ s.date = Time.now.strftime('%Y-%m-%d')
15
+
16
+ s.rubyforge_project = "filter"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_development_dependency "rspec"
24
+ end
data/lib/filter.rb ADDED
@@ -0,0 +1,74 @@
1
+ # == Synpsys
2
+ # Extension for Ruby Enumerable module
3
+ #
4
+ # == Description
5
+ # Extends Enumerable module with +filter+ method - enhanced version of Enumerable#select
6
+ #
7
+ # == Examples
8
+ # [1, 2, 3, 'ab'].filter(/a/) # => #<Enumerator: ['ab']>
9
+ # [1, 2, 3].filter(&:even?) # => #<Enumerator: [2]>
10
+ # [1, 2, 3, 4.2].filter :to_i => :even? # => #<Enumerator: [2, 4]>
11
+ # [1, 2, 4].filter { |num| num.even? } # => #<Enumerator: [2, 4]>
12
+ # [1, 2, 4].filter(:even?) { |n| n + 1 } # => #<Enumerator: [3, 5]>
13
+ # [0, false, 2, nil].filter(true) # => #<Enumerator: [0, 2]>
14
+ module Enumerable
15
+ # Extended Enumerable#select combibed with Enumerable#collect
16
+ #
17
+ # When String or Regexp passed it acts as built-in +grep+ method, but return Enumerator instead of Array
18
+ # Also you can pass Symbol, Proc or block
19
+ #
20
+ # @param pattern [Numeric|String|Regexp|Symbol|Proc|Method|NilClass|Hash|TrueClass|FalseClass|Module|Class]
21
+ # @param block [Proc]
22
+ def filter(pattern = nil, &block) # :yields: obj
23
+ pattern, block = block, nil if block_given? && pattern.nil?
24
+
25
+ filtered = case pattern
26
+ when NilClass then lazy_select { true }
27
+
28
+ when Class, Module then
29
+ lazy_select do |e|
30
+ e.is_a?(Class) || e.is_a?(Module) ?
31
+ e <= pattern :
32
+ e.is_a?(pattern)
33
+ end
34
+
35
+ when Symbol, Proc, Method then lazy_select(&pattern.to_proc)
36
+
37
+ when Array then # enum.filter [:even?, :positive?, :cool?, proc { |n| n < 10 }]
38
+ pattern.reduce(self) do |chain, local_pattern|
39
+ chain.lazy_select(&local_pattern.to_proc)
40
+ end
41
+
42
+ when Hash then # enum.filter :to_i => :even?, :ceil => :odd?
43
+ pattern.reduce(self) do |chain, pair|
44
+ attr, local_pattern = pair.map(&:to_proc)
45
+
46
+ chain.lazy_select do |element|
47
+ local_pattern.call(attr.call(element))
48
+ end
49
+ end
50
+
51
+ when TrueClass, FalseClass then lazy_select { |e| !!e == pattern }
52
+
53
+ else lazy_select { |e| pattern === e } # otherwise - String, Regexp, Numeric etc.
54
+ end
55
+
56
+ # also transform elements if block given
57
+ block ? filtered.lazy_map(&block) : filtered
58
+ end
59
+
60
+ protected
61
+ # Lazy version of built-in Enumerable#select
62
+ def lazy_select
63
+ Enumerator.new do |yielder|
64
+ each { |entry| yielder << entry if yield(entry) }
65
+ end
66
+ end
67
+
68
+ # Lazy version of built-in Enumerable#collect
69
+ def lazy_map #:nodoc:
70
+ Enumerator.new do |yielder|
71
+ each { |entry| yielder << yield(entry) }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module Filter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Enumerable do
4
+ it "should return Enumerator" do
5
+ result = [1, 2, 3].filter
6
+
7
+ result.should be_a(Enumerator)
8
+ end
9
+
10
+ it "should return equivalent Enumerator on null input" do
11
+ [1, 2].filter.to_a.should == [1, 2]
12
+ end
13
+
14
+ it "should match regular expressions" do
15
+ [1, 2, 3, 'ba'].filter(/ba/).to_a.should == ['ba']
16
+ end
17
+
18
+ it "should match against symbols" do
19
+ [1, 2, 3].filter(:even?).to_a.should == [2]
20
+ end
21
+
22
+ it "should match against lambdas" do
23
+ [1, 2, 3].filter(lambda{|n| n.even?}).to_a.should == [2]
24
+ end
25
+
26
+ it "should match against blocks" do
27
+ [1, 2, 3].filter { |n| n.even? }.to_a.should == [2]
28
+ end
29
+
30
+ it "should support #map" do
31
+ [1, 2, 3].filter(:even?) { |n| n + 1 }.to_a.should == [3]
32
+ end
33
+
34
+ it "should match against Hash" do
35
+ [1, 2, 3, 4.2].filter(:to_i => :even?).to_a.should == [2, 4.2]
36
+ [2, 3, 4.2].filter(:to_i => :even?, :ceil => :odd?).to_a.should == [4.2]
37
+ end
38
+
39
+ it "should match against Class and Module" do
40
+ c = Class.new {}
41
+ m = Module.new {}
42
+ i = c.new
43
+
44
+ [c, i, 1].filter(c).to_a.should == [c, i]
45
+ [c, m, i, 1].filter(m).to_a.should == [m]
46
+ end
47
+
48
+ it "should match against Array" do
49
+ [0, 1].filter([:even?, :zero?]).to_a.should == [0]
50
+ end
51
+
52
+ it "should match against true or false" do
53
+ [0, false, 2, nil].filter(true).to_a.should == [0, 2]
54
+ [0, false, 2, nil].filter(false).to_a.should == [false, nil]
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup
4
+
5
+ require "filter"
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: filter
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Alexey Mikhaylov
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-12-11 00:00:00 +06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ description: "== Synopsys\n\
34
+ Enumerable#filter - extended Enumerable#select\n\n\
35
+ == Examples\n\
36
+ String filter (acts like Enumerable#grep):\n [1, 2, 3, 'ab'].filter(/a/) # => #<Enumerator: ['ab']>\n [1, 2, 3, '3'].filter('3') # => #<Enumerator: ['3']>\n\n\
37
+ You can pass a <tt>Proc</tt> or <tt>Symbol</tt>. Methods and blocks are allowed too:\n [1, 2, 3].filter(&:even?) # => #<Enumerator: [2]>\n [1, 2, 3].filter(:even?) # => #<Enumerator: [2]>\n [1, 2, 4].filter { |num| num.even? } # => #<Enumerator: [2, 4]>\n\n\
38
+ <tt>Enumerable#filter</tt> can match against enumerable items attributes. Like this:\n [1, 2, 3, 4.2].filter :to_i => :even? # => #<Enumerator: [2, 4]>\n\n\
39
+ If the block is supplied, each matching element is passed to it, and the block\xE2\x80\x99s result is stored in the output enumerator.\n [1, 2, 4].filter(&:even?) { |n| n + 1 } # => #<Enumerator: [3, 5]>\n\n\
40
+ <tt>Enumerable#filter</tt> also accepts <tt>true</tt> or <tt>false</tt> as argument:\n [0, false, 2, nil].filter(true) # => #<Enumerator: [0, 2]>\n [0, false, 2, nil].filter(false) # => #<Enumerator: [false, nil]>\n"
41
+ email:
42
+ - amikhailov83@gmail.com
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ files:
50
+ - .gitignore
51
+ - Gemfile
52
+ - LICENSE
53
+ - README.rdoc
54
+ - Rakefile
55
+ - filter.gemspec
56
+ - lib/filter.rb
57
+ - lib/filter/version.rb
58
+ - spec/filter_spec.rb
59
+ - spec/test_helper.rb
60
+ has_rdoc: true
61
+ homepage: https://github.com/take-five/filter
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: filter
88
+ rubygems_version: 1.3.7
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Enumerable#filter - extended Enumerable#select combined with Enumerable#collect
92
+ test_files: []
93
+