enumerable_lz 0.1.4 → 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ad8aeb48998541b0d13a8e20a63aa5d2b6af5ba
4
+ data.tar.gz: 7f66a110548e37e864bee992327c67ad36580dd4
5
+ SHA512:
6
+ metadata.gz: b7847ff329ce9a00831d66525d7dc5f91fadbe4f33a3a249dcc1cea959eaef37795ab0648e127be80b26ae1a3a83d913a304aa9670b2f76d7269b379a5f9fcbe
7
+ data.tar.gz: 5511760da227ab917f450a4c9c2af7475d5e88923a374de2d8b1a780edb909fcc1b30b81d9b3c79f5c560e881c22c9a831a4ac900c80f4e1f49487ace01aa745
data/ChangeLog CHANGED
@@ -14,3 +14,9 @@
14
14
 
15
15
  * Improve performance much more
16
16
 
17
+ == 0.1.5 / 2014-01-08
18
+
19
+ * Add `filter.with_index` and `transform.with_index` feature
20
+ * Add `filter.with_initializer` feature (and obsolete `filter_with_initproc` method)
21
+ * Add support for Ruby 2.0.0/2.1.0
22
+ * Improve performance
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2011 GOTOH Shunsuke (@antimon2)
3
+ Copyright (c) 2011,2014 GOTOH Shunsuke (@antimon2)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -9,17 +9,32 @@ Also it provides lazy equivalents of some methods in `Enumerable`.
9
9
  When require 'enumerable_lz', these lazy methods are provided:
10
10
 
11
11
  * `Enumerable#filter`
12
- * `Enumerable#filter_with_initproc`
13
12
  * `Enumerable#transform`
14
13
 
15
- For example (in Ruby 1.9.x):
14
+ And some method-chains are provided:
15
+
16
+ * `Enumerable#filter.with_index`
17
+ * `Enumerable#filter.with_initializer`
18
+ * `Enumerable#transform.with_index`
19
+
20
+ For example (in Ruby 1.9.x or greater):
16
21
 
17
22
  require 'enumerable_lz'
18
23
  require 'prime'
19
-
24
+
20
25
  (1..Float::INFINITY).transform{|n|n**2+1}.filter{|m|m.prime?}.take(100)
21
26
  # => [2, 5, ... , 682277, 739601] for a few msec.
22
27
 
28
+ Prime.filter.with_index{|q,i|i.odd?}.take(10)
29
+ # => [3, 7, 13, 19, 29, 37, 43, 53, 61, 71]
30
+
31
+ Prime.transform.with_index{|q,i|[q,i]}.take(10)
32
+ # => [[2, 0], [3, 1], [5, 2], [7, 3], [11, 4], [13, 5], [17, 6], [19, 7], [23, 8], [29, 9]]
33
+
34
+ # especially, when calling transform.with_index without a block
35
+ Prime.transform.with_index.take(10)
36
+ # => [[2, 0], [3, 1], [5, 2], [7, 3], [11, 4], [13, 5], [17, 6], [19, 7], [23, 8], [29, 9]]
37
+
23
38
 
24
39
  ## Expanded Usage
25
40
 
@@ -37,7 +52,7 @@ When require 'enumerable_lz/enumerable_ex', some lazy methods equivalents to ori
37
52
  * `Enumerable#take_while_lz`
38
53
 
39
54
 
40
- For example (in Ruby 1.9.x):
55
+ For example (in Ruby 1.9.x or greater):
41
56
 
42
57
  require 'enumerable_lz'
43
58
  require 'enumerable_lz/enumerable_ex'
@@ -51,10 +66,12 @@ These expanded methods are inplemented with fundamental filter and transformatio
51
66
 
52
67
  ## Supported Rubies
53
68
 
54
- * Ruby 1.9.x (testing 1.9.2 p-180)
55
- * Ruby 1.8.7 (testing 1.8.7-p334)
56
- * JRuby (testing 1.5.6, 1.6.0)
57
- * MacRuby (testing 0.9)
69
+ * Ruby 2.1.0 (testing 2.1.0-p0)
70
+ * Ruby 2.0.0 (testing 2.0.0-p247)
71
+ * Ruby 1.9.x (testing 1.9.3-p448)
72
+ * Ruby 1.8.7 (testing 1.8.7-p358)
73
+ * JRuby (testing 1.7.2)
74
+ * MacRuby (testing 0.12)
58
75
 
59
76
  ## Installation
60
77
 
@@ -64,6 +81,6 @@ These expanded methods are inplemented with fundamental filter and transformatio
64
81
  ## License
65
82
 
66
83
  The MIT License
67
- Copyright (c) 2011 GOTOH Shunsuke (@antimon2)
84
+ Copyright (c) 2011, 2014 GOTOH Shunsuke (@antimon2)
68
85
 
69
86
  Please see [LICENSE.txt](LICENSE.txt) for details.
data/lib/enumerable_lz.rb CHANGED
@@ -11,8 +11,48 @@ else
11
11
  require File.dirname(__FILE__)+'/enumerable_lz/transform_18'
12
12
  end
13
13
 
14
+ # add {#filter} and {#transform} methods.
14
15
  module Enumerable
16
+ # @!group Fundamental Method Summary
17
+
18
+ # Filter by pattern or block
19
+ # @yield [el]
20
+ # @overload filter(&block)
21
+ # filter by block
22
+ # @yield [el] filterring block.
23
+ # @yieldparam el each element of original Enumerable
24
+ # @yieldreturn [Boolean]
25
+ # @return [Enumerator::Filter]
26
+ # @overload filter(pattern)
27
+ # filter by pattern
28
+ # @param [#===] pattern filterring pattern. (uses === method)
29
+ # @return [Enumerator::Filter]
30
+ # @return [Enumerator::Filter]
31
+ def filter pattern = nil, &block
32
+ Enumerator::Filter.new self, pattern||block
33
+ end
34
+
35
+ # @yield [el]
36
+ # @deprecated Use filter.with_initializer instead of this method
37
+ # @see Enumerator::Filter#with_initializer
38
+ # @return [Enumerator::Filter]
39
+ def filter_with_initproc init_proc, pattern = nil, &block
40
+ filter.with_initializer init_proc, pattern = nil, &block
41
+ end
42
+
43
+ # Transform by block
44
+ # @yield [el] transform block.
45
+ # @yieldparam el each element of original Enumerable
46
+ # @yieldreturn [Object]
47
+ # @return [Enumerator::Transform]
48
+ def transform &block
49
+ Enumerator::Transform.new self, &block
50
+ end
51
+
52
+ # @!endgroup
53
+
54
+ # @private
15
55
  module EnumerableLz
16
- VERSION = "0.1.4"
56
+ VERSION = "0.1.5"
17
57
  end
18
- end
58
+ end
@@ -1,49 +1,91 @@
1
1
  require File.expand_path('..', __FILE__)
2
2
 
3
3
  module Enumerable
4
+ # @!group Expanded Method Summary
5
+
6
+ # lazy equivalent of `Enumerable#select`
7
+ # @yield [el]
8
+ # @note available only requiring "enumerable_lz/enumerable_ex"
9
+ # @return [Enumerator::Filter]
4
10
  def select_lz &block
5
11
  filter &block
6
12
  end
7
-
8
13
  alias :find_all_lz :select_lz
9
14
 
15
+ # lazy equivalent of `Enumerable#reject`
16
+ # @yield [el]
17
+ # @note available only requiring "enumerable_lz/enumerable_ex"
18
+ # @return [Enumerator::Filter]
10
19
  def reject_lz &block
11
20
  filter {|e|!block.call(e)}
12
21
  end
13
22
 
23
+ # lazy equivalent of `Enumerable#grep`
24
+ # @yield [el]
25
+ # @note available only requiring "enumerable_lz/enumerable_ex"
26
+ # @overload grep_lz(pattern)
27
+ # @return [Enumerator::Filter]
28
+ # @overload grep_lz(pattern, &block)
29
+ # @yield [el]
30
+ # @return [Enumerator::Transform]
31
+ # @return [Enumerator::Filter, Enumerator::Transform]
14
32
  def grep_lz pattern, &block
15
33
  enum = filter pattern
16
34
  block_given? ? enum.transform(&block) : enum
17
35
  end
18
36
 
19
- alias :map_lz :transform
37
+ # @!method map_lz(&block)
38
+ # lazy equivalent of `Enumerable#map`
39
+ # @yield [el]
40
+ # @note available only requiring "enumerable_lz/enumerable_ex"
41
+ # @return [Enumerator::Transform]
42
+ self.__send__(:alias_method, :map_lz, :transform)
20
43
  alias :collect_lz :map_lz
21
44
 
45
+ # lazy equivalent of `Enumerable#drop`
46
+ # @note available only requiring "enumerable_lz/enumerable_ex"
47
+ # @return [Enumerator::Filter]
22
48
  def drop_lz n
23
49
  raise ArgumentError, "attempt to take negative size" if n < 0
24
50
  # each_with_index.filter{|el,idx|idx >= n}.transform{|el,idx|el}
25
- cnt = 0
26
- filter_with_initproc(Proc.new{cnt=0}) {|el| (cnt+=1) > n}
51
+ # cnt = 0
52
+ # filter_with_initproc(Proc.new{cnt=0}) {|el| (cnt+=1) > n}
53
+ filter.with_index {|el, i| i >= n}
27
54
  end
28
55
 
56
+ # lazy equivalent of `Enumerable#drop_while`
57
+ # @yield [el]
58
+ # @note available only requiring "enumerable_lz/enumerable_ex"
59
+ # @return [Enumerator::Filter]
29
60
  def drop_while_lz &block
30
61
  return self if !block_given?
31
62
  flg = false
32
- filter_with_initproc(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
63
+ # filter_with_initproc(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
64
+ filter.with_initializer(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
33
65
  end
34
66
 
67
+ # lazy equivalent of `Enumerable#take`
68
+ # @note available only requiring "enumerable_lz/enumerable_ex"
69
+ # @return [Enumerator::Filter]
35
70
  def take_lz n
36
71
  raise ArgumentError, "attempt to take negative size" if n < 0
37
72
  # each_with_index.filter{|el,idx|throw :do_break if idx >= n;true}.transform{|el,idx|el}
38
- cnt = 0
39
- filter_with_initproc(Proc.new{cnt=0}) {|el| throw :do_break if (cnt+=1) > n;true}
73
+ # cnt = 0
74
+ # filter_with_initproc(Proc.new{cnt=0}) {|el| throw :do_break if (cnt+=1) > n;true}
75
+ filter.with_index {|el, i| throw :do_break if i >= n; true}
40
76
  end
41
77
 
78
+ # lazy equivalent of `Enumerable#take_while`
79
+ # @yield [el]
80
+ # @note available only requiring "enumerable_lz/enumerable_ex"
81
+ # @return [Enumerator::Filter]
42
82
  def take_while_lz &block
43
83
  return self if !block_given?
44
- filter {|el|throw :do_break unless block.call(el);true}
84
+ filter {|el|throw :do_break unless block.call(el); true}
45
85
  end
46
86
 
87
+ # @!endgroup
88
+
47
89
  # def zip_lz *lists
48
90
  # enums = lists.map{|list|list.each rescue [].each}
49
91
  # Enumerator.new do |y|
@@ -1,21 +1,14 @@
1
- # for Ruby1.9.x except for MacRuby
2
- module Enumerable
3
- def filter pattern = nil, &block
4
- Filter.new self, pattern||block
5
- end
6
-
7
- def filter_with_initproc init_proc, pattern = nil, &block
8
- Filter.new self, init_proc, pattern||block
9
- end
1
+ # -- for Ruby1.9.x except for MacRuby
10
2
 
3
+ # add [Filter] and [Transform] classes.
4
+ class Enumerator
5
+ # Lazy Filterring Enumerator
11
6
  class Filter < Enumerator
12
- def initialize obj, *args
13
- the_filter = args.shift
14
- init_block, the_filter = [the_filter, args.shift] unless args.empty?
7
+ # @param [Enumerable] obj an Enumerable.
8
+ # @param [#===] the_filter filterring pattern or proc.
9
+ def initialize obj, the_filter=nil
15
10
  @org_enum = obj
16
- @init_block = init_block unless init_block.nil?
17
11
  super() do |y|
18
- @init_block.call unless @init_block.nil?
19
12
  compiled_filter = @filter.nil? ? Proc.new{true} : lambda{|f|
20
13
  break f[0] if f.size==1
21
14
  codes = f.size.times.map do |idx|
@@ -32,6 +25,9 @@ module Enumerable
32
25
  filter! the_filter if the_filter
33
26
  end
34
27
 
28
+ # Apply filter pattern/block and return self. (bang method of filter)
29
+ # @yield [el]
30
+ # @return [Filter] self
35
31
  def filter! pattern=nil, &block
36
32
  @filter||=[]
37
33
  if pattern.is_a? Array
@@ -42,9 +38,15 @@ module Enumerable
42
38
  self
43
39
  end
44
40
 
45
- #[override]
41
+ # [override] for performance
42
+ # @yield [el]
43
+ # @overload filter(&block)
44
+ # @yield [el]
45
+ # @overload filter(pattern)
46
+ # @param [#===] pattern
47
+ # @see Enumerable#filter Enumerable#filter
48
+ # @return [Filter]
46
49
  def filter pattern=nil, &block
47
- return super unless @init_block.nil?
48
50
  # clone.filter! pattern, &block
49
51
  patterns = @filter.nil? ? [] : @filter.clone
50
52
  if pattern.is_a? Array
@@ -55,6 +57,33 @@ module Enumerable
55
57
  Filter.new @org_enum, patterns
56
58
  end
57
59
 
60
+ # @overload with_initializer(init_proc, &block)
61
+ # filter by block with initializer proc.
62
+ # @param [#call] init_proc initializer proc. (uses .call method)
63
+ # @yield filterring block.
64
+ # @return [Filter]
65
+ # @overload with_initializer(init_proc, pattern)
66
+ # filter by pattern with initializer proc.
67
+ # @param [#call] init_proc initializer proc. (uses .call method)
68
+ # @param [#===] pattern filterring pattern. (uses === method)
69
+ # @return [Filter]
70
+ # @return [Filter]
71
+ def with_initializer init_proc, pattern = nil, &block
72
+ src_enum = @filter.nil? ? @org_enum : self
73
+ FilterWithInitializer.new src_enum, init_proc, pattern||block
74
+ end
75
+
76
+ # @param [Numeric] offset offset.
77
+ # @yield [el, i]
78
+ # @return [Filter]
79
+ def with_index offset=0, &block
80
+ raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
81
+ i = offset - 1
82
+ with_initializer(Proc.new{i = offset - 1}) do |el|
83
+ block.call(el, i += 1)
84
+ end
85
+ end
86
+
58
87
  private
59
88
  def conv_proc pattern
60
89
  case pattern
@@ -65,9 +94,31 @@ module Enumerable
65
94
  end
66
95
  end
67
96
  end
97
+
98
+ # @api private
99
+ class FilterWithInitializer < Filter
100
+ def initialize obj, init_block, the_filter = nil
101
+ super obj, the_filter
102
+ @initializer = init_block
103
+ end
104
+
105
+ def each &block
106
+ return self unless block_given?
107
+ @initializer.call
108
+ super &block
109
+ end
110
+
111
+ # @see Enumerable#filter Enumerable#filter
112
+ # @return [Filter]
113
+ def filter pattern=nil, &block
114
+ Filter.new self, pattern||block
115
+ end
116
+ end
117
+ private_constant :FilterWithInitializer if self.respond_to? :private_constant
68
118
  end
69
- #against the Bug on JRuby <1.6.2
119
+ # against the Bug on JRuby < 1.6.2
70
120
  if !(Proc.new{true}===true)
121
+ # @private
71
122
  class Proc
72
123
  alias :=== :call
73
124
  end
@@ -1,76 +1,99 @@
1
1
  # for Ruby1.8.7
2
+
2
3
  module Enumerable
3
- def filter pattern = nil, &block
4
- Filter.new self, pattern||block
5
- end
4
+ class Enumerator
5
+ class Filter < Enumerator
6
+ def initialize obj, the_filter=nil
7
+ filter! the_filter if the_filter
8
+ @org_enum = obj
9
+ end
6
10
 
7
- def filter_with_initproc init_proc, pattern = nil, &block
8
- Filter.new self, init_proc, pattern||block
9
- end
11
+ def each &block
12
+ return self unless block_given?
13
+ # compiled_filter = (@filter||[Proc.new{true}]).inject do |r,f|
14
+ # Proc.new{|el| r[el] && f[el]}
15
+ # end
16
+ compiled_filter = @filter.nil? ? Proc.new{true} : lambda{|f|
17
+ break f[0] if f.size==1
18
+ codes = f.size.times.map do |idx|
19
+ "f[#{idx}][el]"
20
+ end
21
+ eval "Proc.new{|el|"+codes.join(" && ")+"}"
22
+ }.call(@filter)
23
+ catch :do_break do
24
+ @org_enum.each do |el|
25
+ block.call(el) if compiled_filter[el]
26
+ end
27
+ end
28
+ self
29
+ end
10
30
 
11
- class Filter < Enumerator
12
- def initialize obj, *args
13
- the_filter = args.shift
14
- init_block, the_filter = [the_filter, args.shift] unless args.empty?
15
- filter! the_filter if the_filter
16
- @org_enum = obj
17
- @init_block = init_block unless init_block.nil?
18
- end
31
+ def filter! pattern=nil, &block
32
+ @filter||=[]
33
+ if pattern.is_a? Array
34
+ pattern.each{|el| @filter << conv_proc(el)}
35
+ else
36
+ @filter << conv_proc(pattern || block)
37
+ end
38
+ self
39
+ end
19
40
 
20
- def each &block
21
- return self unless block_given?
22
- @init_block.call unless @init_block.nil?
23
- # compiled_filter = (@filter||[Proc.new{true}]).inject do |r,f|
24
- # Proc.new{|el| r[el] && f[el]}
25
- # end
26
- compiled_filter = @filter.nil? ? Proc.new{true} : lambda{|f|
27
- break f[0] if f.size==1
28
- codes = f.size.times.map do |idx|
29
- "f[#{idx}][el]"
41
+ #[override]
42
+ def filter pattern=nil, &block
43
+ # clone.filter! pattern, &block
44
+ patterns = @filter.nil? ? [] : @filter.clone
45
+ if pattern.is_a? Array
46
+ patterns.push(*pattern)
47
+ else
48
+ patterns << (pattern || block)
30
49
  end
31
- eval "Proc.new{|el|"+codes.join(" && ")+"}"
32
- }.call(@filter)
33
- catch :do_break do
34
- @org_enum.each do |el|
35
- block.call(el) if compiled_filter[el]
50
+ Filter.new @org_enum, patterns
51
+ end
52
+
53
+ def with_initializer init_proc, pattern = nil, &block
54
+ src_enum = @filter.nil? ? @org_enum : self
55
+ FilterWithInitializer.new src_enum, init_proc, pattern||block
56
+ end
57
+
58
+ #[override]
59
+ def with_index offset=0, &block
60
+ raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
61
+ i = offset - 1
62
+ with_initializer(Proc.new{i = offset - 1}) do |el|
63
+ block.call(el, i += 1)
36
64
  end
37
65
  end
38
- self
39
- end
40
66
 
41
- def filter! pattern=nil, &block
42
- @filter||=[]
43
- if pattern.is_a? Array
44
- pattern.each{|el| @filter << conv_proc(el)}
45
- else
46
- @filter << conv_proc(pattern || block)
67
+ private
68
+ def conv_proc pattern
69
+ case pattern
70
+ when nil
71
+ Proc.new{true}
72
+ when Proc
73
+ pattern
74
+ else
75
+ pattern.respond_to?(:to_proc) ? pattern.to_proc : Proc.new{|el|pattern===el}
76
+ end
47
77
  end
48
- self
49
78
  end
50
79
 
51
- #[override]
52
- def filter pattern=nil, &block
53
- return super unless @init_block.nil?
54
- # clone.filter! pattern, &block
55
- patterns = @filter.nil? ? [] : @filter.clone
56
- if pattern.is_a? Array
57
- patterns.push(*pattern)
58
- else
59
- patterns << (pattern || block)
80
+ # private
81
+ class FilterWithInitializer < Filter
82
+ def initialize obj, init_block, the_filter = nil
83
+ super obj, the_filter
84
+ @initializer = init_block
85
+ end
86
+
87
+ def each &block
88
+ return self unless block_given?
89
+ @initializer.call
90
+ super &block
60
91
  end
61
- Filter.new @org_enum, patterns
62
- end
63
92
 
64
- private
65
- def conv_proc pattern
66
- case pattern
67
- when nil
68
- Proc.new{true}
69
- when Proc
70
- pattern
71
- else
72
- pattern.respond_to?(:to_proc) ? pattern.to_proc : Proc.new{|el|pattern===el}
93
+ #[override]
94
+ def filter pattern=nil, &block
95
+ Filter.new self, pattern||block
73
96
  end
74
97
  end
75
98
  end
76
- end
99
+ end
@@ -1,24 +1,15 @@
1
1
  # for MacRuby
2
- module Enumerable
3
- def filter pattern = nil, &block
4
- Filter.new self, pattern||block
5
- end
6
-
7
- def filter_with_initproc init_proc, pattern = nil, &block
8
- Filter.new self, init_proc, pattern||block
9
- end
10
2
 
3
+ class Enumerator
11
4
  class Filter < Enumerator
12
- def initialize obj, *args
13
- the_filter = args.shift
14
- init_block, the_filter = [the_filter, args.shift] unless args.empty?
5
+ TrueProc = Proc.new{true}
6
+
7
+ def initialize obj, the_filter = nil
15
8
  @org_enum = obj
16
- @init_block = init_block unless init_block.nil?
17
9
  outer = self
18
10
  super Class.new {
19
11
  define_method :each do
20
12
  return outer unless block_given?
21
- init_block.call unless init_block.nil?
22
13
  compiled_filter = outer.__send__(:compile_filter)
23
14
  catch :do_break do
24
15
  obj.each do |el|
@@ -50,10 +41,23 @@ module Enumerable
50
41
  else
51
42
  patterns<<(pattern || block)
52
43
  end
53
- return Filter.new @org_enum, @init_block, patterns unless @init_block.nil?
54
44
  Filter.new @org_enum, patterns
55
45
  end
56
46
 
47
+ def with_initializer init_proc, pattern = nil, &block
48
+ src_enum = @filter.nil? ? @org_enum : self
49
+ FilterWithInitializer.new src_enum, init_proc, pattern||block
50
+ end
51
+
52
+ #[override]
53
+ def with_index offset=0, &block
54
+ raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
55
+ i = offset - 1
56
+ patterns = @filter.nil? ? [] : @filter.clone
57
+ patterns << Proc.new{|el| block.call(el, i += 1)}
58
+ FilterWithInitializer.new @org_enum, Proc.new{i = offset - 1}, patterns
59
+ end
60
+
57
61
  private
58
62
  def conv_proc pattern
59
63
  case pattern
@@ -74,4 +78,23 @@ module Enumerable
74
78
  }.call(@filter)
75
79
  end
76
80
  end
81
+
82
+ # private
83
+ class FilterWithInitializer < Filter
84
+ def initialize obj, init_block, the_filter = nil
85
+ super obj, the_filter
86
+ @initializer = init_block
87
+ end
88
+
89
+ def each &block
90
+ return self unless block_given?
91
+ @initializer.call
92
+ super &block
93
+ end
94
+
95
+ #[override]
96
+ def filter pattern=nil, &block
97
+ Filter.new self, pattern||block
98
+ end
99
+ end
77
100
  end
@@ -1,10 +1,11 @@
1
- # for Ruby1.9.x except for MacRuby
2
- module Enumerable
3
- def transform &block
4
- Transform.new self, &block
5
- end
1
+ # -- for Ruby1.9.x except for MacRuby
6
2
 
3
+ # add [Filter] and [Transform] classes.
4
+ class Enumerator
5
+ # Lazy Transform Enumerator
7
6
  class Transform < Enumerator
7
+ # @param [Enumerable] obj an Enumerable.
8
+ # @yield transform block.
8
9
  def initialize obj, &transformer
9
10
  @org_enum = obj
10
11
  super() do |y|
@@ -16,13 +17,19 @@ module Enumerable
16
17
  transform! &transformer if block_given?
17
18
  end
18
19
 
20
+ # Apply another transformer block and return self. (bang method of transform)
21
+ # @yield [el] transform block.
22
+ # @return [Transform] self
19
23
  def transform! &block
20
24
  @transformer||=[]
21
25
  @transformer << block if block_given?
22
26
  self
23
27
  end
24
28
 
25
- #[override]
29
+ # [override] for performance
30
+ # @yield [el] transform block.
31
+ # @see Enumerable#transform Enumerable#transform
32
+ # @return [Transform]
26
33
  def transform &block
27
34
  # clone.transform! &block
28
35
  cp = Transform.new @org_enum
@@ -32,6 +39,22 @@ module Enumerable
32
39
  cp.transform! &block
33
40
  end
34
41
 
42
+ # @yield [el, i]
43
+ # @overload with_index(offset=0, &block)
44
+ # @param [Numeric] offset offset.
45
+ # @yield [el, i]
46
+ # @return [Transform]
47
+ # @overload with_index(offset=0)
48
+ # @note same as with_index(offset) {|el, i| [el, i]}
49
+ # @param [Numeric] offset offset.
50
+ # @return [Transform]
51
+ # @return [Transform]
52
+ def with_index offset=0, &block
53
+ src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
54
+ block ||= Proc.new{|el, i|[el, i]}
55
+ TransformWithIndex.new src_enum, offset, &block
56
+ end
57
+
35
58
  private
36
59
  def compile_transformer
37
60
  return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
@@ -44,4 +67,30 @@ module Enumerable
44
67
  }.call(@transformer)
45
68
  end
46
69
  end
70
+
71
+ # @api private
72
+ class TransformWithIndex < Transform
73
+ def initialize obj, offset = 0, &transformer
74
+ @org_enum = obj
75
+ @transformer = transformer.nil? ? nil : [transformer]
76
+ @offset = offset
77
+ end
78
+
79
+ def each
80
+ return self unless block_given?
81
+ the_transformer = @transformer[0] || Proc.new{|el,i|el}
82
+ i = @offset - 1
83
+ @org_enum.each do |el|
84
+ yield the_transformer.call(el, i+=1)
85
+ end
86
+ end
87
+
88
+ # @see Enumerable#filter Enumerable#filter
89
+ # @return [Transform]
90
+ def transform &block
91
+ Transform.new self, &block
92
+ end
93
+ alias :transform! :transform
94
+ end
95
+ private_constant :TransformWithIndex if self.respond_to? :private_constant
47
96
  end
@@ -1,50 +1,79 @@
1
1
  # for Ruby1.8.7
2
2
  module Enumerable
3
- def transform &block
4
- Transform.new self, &block
5
- end
3
+ class Enumerator
4
+ class Transform < Enumerator
5
+ def initialize obj, &transformer
6
+ @org_enum = obj
7
+ transform! &transformer if block_given?
8
+ end
6
9
 
7
- class Transform < Enumerator
8
- def initialize obj, &transformer
9
- @org_enum = obj
10
- transform! &transformer if block_given?
11
- end
10
+ def each &block
11
+ return self unless block_given?
12
+ the_transformer = compile_transformer
13
+ @org_enum.each do |el|
14
+ block.call the_transformer[el]
15
+ end
16
+ self
17
+ end
12
18
 
13
- def each &block
14
- return self unless block_given?
15
- the_transformer = compile_transformer
16
- @org_enum.each do |el|
17
- block.call the_transformer[el]
19
+ def transform! &block
20
+ @transformer||=[]
21
+ @transformer << block if block_given?
22
+ self
18
23
  end
19
- self
20
- end
21
24
 
22
- def transform! &block
23
- @transformer||=[]
24
- @transformer << block if block_given?
25
- self
26
- end
25
+ #[override]
26
+ def transform &block
27
+ # clone.transform! &block
28
+ cp = Transform.new @org_enum
29
+ @transformer.each do |org_block|
30
+ cp.transform! &org_block
31
+ end unless @transformer.nil?
32
+ cp.transform! &block
33
+ end
27
34
 
28
- #[override]
29
- def transform &block
30
- # clone.transform! &block
31
- cp = Transform.new @org_enum
32
- @transformer.each do |org_block|
33
- cp.transform! &org_block
34
- end unless @transformer.nil?
35
- cp.transform! &block
35
+ #[override]
36
+ def with_index offset=0, &block
37
+ src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
38
+ block ||= Proc.new{|el, i|[el, i]}
39
+ TransformWithIndex.new src_enum, offset, &block
40
+ end
41
+
42
+ private
43
+ def compile_transformer
44
+ return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
45
+ return @transformer[0] if @transformer.size==1
46
+ lambda{|t|
47
+ codes = t.size.times.inject "el" do |r,idx|
48
+ "t[#{idx}][#{r}]"
49
+ end
50
+ eval "Proc.new{|el|"+codes+"}"
51
+ }.call(@transformer)
52
+ end
36
53
  end
37
54
 
38
- private
39
- def compile_transformer
40
- return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
41
- return @transformer[0] if @transformer.size==1
42
- lambda{|t|
43
- codes = t.size.times.inject "el" do |r,idx|
44
- "t[#{idx}][#{r}]"
55
+ # private
56
+ class TransformWithIndex < Transform
57
+ def initialize obj, offset = 0, &transformer
58
+ @org_enum = obj
59
+ @transformer = transformer.nil? ? nil : [transformer]
60
+ @offset = offset
61
+ end
62
+
63
+ def each
64
+ return self unless block_given?
65
+ the_transformer = @transformer[0] || Proc.new{|el,i|el}
66
+ i = @offset - 1
67
+ @org_enum.each do |el|
68
+ yield the_transformer.call(el, i+=1)
45
69
  end
46
- eval "Proc.new{|el|"+codes+"}"
47
- }.call(@transformer)
70
+ end
71
+
72
+ #[override]
73
+ def transform &block
74
+ Transform.new self, &block
75
+ end
76
+ alias :transform! :transform
48
77
  end
49
78
  end
50
79
  end
@@ -1,9 +1,5 @@
1
1
  # for MacRuby
2
- module Enumerable
3
- def transform &block
4
- Transform.new self, &block
5
- end
6
-
2
+ class Enumerator
7
3
  class Transform < Enumerator
8
4
  def initialize obj, &transformer
9
5
  @org_enum = obj
@@ -36,6 +32,13 @@ module Enumerable
36
32
  cp.transform! &block
37
33
  end
38
34
 
35
+ #[override]
36
+ def with_index offset=0, &block
37
+ src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
38
+ block ||= Proc.new{|el, i|[el, i]}
39
+ TransformWithIndex.new src_enum, offset, &block
40
+ end
41
+
39
42
  private
40
43
  def compile_transformer
41
44
  return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
@@ -52,4 +55,28 @@ module Enumerable
52
55
  # }.call(@transformer)
53
56
  end
54
57
  end
58
+
59
+ # private
60
+ class TransformWithIndex < Transform
61
+ def initialize obj, offset = 0, &transformer
62
+ @org_enum = obj
63
+ @transformer = transformer.nil? ? nil : [transformer]
64
+ @offset = offset
65
+ end
66
+
67
+ def each
68
+ return self unless block_given?
69
+ the_transformer = @transformer[0] || Proc.new{|el,i|el}
70
+ i = @offset - 1
71
+ @org_enum.each do |el|
72
+ yield the_transformer.call(el, i+=1)
73
+ end
74
+ end
75
+
76
+ #[override]
77
+ def transform &block
78
+ Transform.new self, &block
79
+ end
80
+ alias :transform! :transform
81
+ end
55
82
  end
data/test/test_filter.rb CHANGED
@@ -3,15 +3,17 @@ require 'enumerable_lz'
3
3
 
4
4
  class FilterTest < Test::Unit::TestCase
5
5
  def test_instance
6
- enum = Enumerable::Filter.new []
6
+ filter_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Filter : Enumerator::Filter
7
+ enum = filter_class.new []
7
8
  assert_not_nil(enum)
8
9
  assert_kind_of(Enumerable, enum)
9
10
  end
10
11
 
11
12
  def test_filter_array
13
+ filter_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Filter : Enumerator::Filter
12
14
  array = %w[Yes I have a number]
13
15
  enum = array.filter{|letters|letters.size > 1}
14
- assert_instance_of(Enumerable::Filter, enum)
16
+ assert_instance_of(filter_class, enum)
15
17
  assert_equal(%w[Yes have number], enum.to_a)
16
18
  end
17
19
 
@@ -85,14 +87,15 @@ class FilterTest < Test::Unit::TestCase
85
87
  assert_same(enum1, enum2)
86
88
  end
87
89
 
88
- def test_init_block
89
- range = -10..10
90
- cnt = 0
91
- init_pr = Proc.new{cnt = 0}
92
- filter_pr = Proc.new{(cnt+=1)<=10}
93
- enum = Enumerable::Filter.new range, init_pr, filter_pr
94
- assert_equal([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1], enum.to_a)
95
- end
90
+ # def test_init_block
91
+ # range = -10..10
92
+ # cnt = 0
93
+ # init_pr = Proc.new{cnt = 0}
94
+ # filter_pr = Proc.new{(cnt+=1)<=10}
95
+ # # enum = Enumerator::FilterWithInitializer.new range, init_pr, filter_pr
96
+ # enum = Enumerator::FilterWithInitializer.new range, init_pr, filter_pr
97
+ # assert_equal([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1], enum.to_a)
98
+ # end
96
99
 
97
100
  def test_filter_with_initproc_1
98
101
  range = -10..10
@@ -122,4 +125,22 @@ class FilterTest < Test::Unit::TestCase
122
125
  enum = range.filter_with_initproc(init_pr) {|n|throw :do_break if (sum+=n)>100;true}
123
126
  assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], enum.to_a)
124
127
  end
128
+
129
+ def test_filetr_with_index
130
+ a = 0
131
+ b = (1..10).filter.with_index{|n,i|a=n;i.even?}.first
132
+ assert_equal([1, 1], [a, b])
133
+ end
134
+
135
+ def test_filetr_with_index_2
136
+ a = 0
137
+ b = (1..10).filter.with_index(1){|n,i|a=n;i.even?}.first
138
+ assert_equal([2, 2], [a, b])
139
+ end
140
+
141
+ def test_filetr_with_index_no_block
142
+ assert_raise(ArgumentError) do
143
+ (1..10).filter.with_index(2).take(2)
144
+ end
145
+ end
125
146
  end
@@ -3,15 +3,17 @@ require 'enumerable_lz'
3
3
 
4
4
  class TransformTest < Test::Unit::TestCase
5
5
  def test_instance
6
- enum = Enumerable::Transform.new []
6
+ transform_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Transform : Enumerator::Transform
7
+ enum = transform_class.new []
7
8
  assert_not_nil(enum)
8
9
  assert_kind_of(Enumerable, enum)
9
10
  end
10
11
 
11
12
  def test_transform_array
13
+ transform_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Transform : Enumerator::Transform
12
14
  array = %w[Yes I have a number]
13
15
  enum = array.transform{|letters|letters.swapcase}
14
- assert_instance_of(Enumerable::Transform, enum)
16
+ assert_instance_of(transform_class, enum)
15
17
  assert_equal(%w[yES i HAVE A NUMBER], enum.to_a)
16
18
  end
17
19
 
@@ -52,4 +54,24 @@ class TransformTest < Test::Unit::TestCase
52
54
  enum2 = enum1.transform!
53
55
  assert_same(enum1, enum2)
54
56
  end
57
+
58
+ def test_transform_with_index
59
+ range = -10..10
60
+ a = 0
61
+ result = range.transform.with_index{|n,i|n+a=i}.take(10)
62
+ assert_equal(9, a)
63
+ end
64
+
65
+ def test_transform_with_index2
66
+ range = -10..10
67
+ a = 0
68
+ result = range.transform.with_index{|n,i|n+a=i}.take(10)
69
+ assert_equal([-10, -8, -6, -4, -2, 0, 2, 4, 6, 8], result)
70
+ end
71
+
72
+ def test_transform_with_index_no_block
73
+ range = -10..10
74
+ result = range.transform.with_index(2).filter{|n,i|n+i<10}.to_a
75
+ assert_equal([[-10, 2], [-9, 3], [-8, 4], [-7, 5], [-6, 6], [-5, 7], [-4, 8], [-3, 9], [-2, 10]], result)
76
+ end
55
77
  end
metadata CHANGED
@@ -1,28 +1,22 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: enumerable_lz
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - antimon2
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2011-05-07 00:00:00 +09:00
14
- default_executable:
11
+ date: 2014-01-08 00:00:00.000000000 Z
15
12
  dependencies: []
16
-
17
- description: Add Enumerable#filter, Enumerable#transform and some equivalent methods on Enumerable with suffix '_lz'.
13
+ description: Add Enumerable#filter, Enumerable#transform and some equivalent methods
14
+ on Enumerable with suffix '_lz'.
18
15
  email: antimon2.me@gmail.com
19
16
  executables: []
20
-
21
17
  extensions: []
22
-
23
18
  extra_rdoc_files: []
24
-
25
- files:
19
+ files:
26
20
  - README.md
27
21
  - LICENSE.txt
28
22
  - ChangeLog
@@ -38,35 +32,35 @@ files:
38
32
  - lib/enumerable_lz/transform_18.rb
39
33
  - lib/enumerable_lz/transform_mrb.rb
40
34
  - lib/enumerable_lz.rb
41
- has_rdoc: true
42
35
  homepage: https://github.com/antimon2/enumerable_lz
43
36
  licenses: []
44
-
37
+ metadata: {}
45
38
  post_install_message:
46
- rdoc_options: []
47
-
48
- require_paths:
39
+ rdoc_options:
40
+ - --no-private
41
+ - --exclude
42
+ - (_mrb|_18)
43
+ require_paths:
49
44
  - lib
50
- required_ruby_version: !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
55
49
  version: 1.8.7
56
- required_rubygems_version: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
62
55
  requirements: []
63
-
64
56
  rubyforge_project: enumerable_lz
65
- rubygems_version: 1.5.3
57
+ rubygems_version: 2.0.3
66
58
  signing_key:
67
59
  specification_version: 3
68
- summary: Add Enumerable#filter, Enumerable#transform and some equivalent methods on Enumerable with suffix '_lz'.
69
- test_files:
60
+ summary: Add Enumerable#filter, Enumerable#transform and some equivalent methods on
61
+ Enumerable with suffix '_lz'.
62
+ test_files:
70
63
  - test/test_enumerable_ex.rb
71
64
  - test/test_filter.rb
72
65
  - test/test_transform.rb
66
+ has_rdoc: yard