backports 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,21 @@
1
1
  = Packable --- History
2
2
 
3
+ == Version 1.2 - April 12, 2009
4
+
5
+ * Array
6
+ * +reverse_each+
7
+ * +cycle+
8
+
9
+ * Enumerable
10
+ * +reverse_each+
11
+ * +each_slice+, +each_cons+
12
+ * +count+
13
+ * +cycle+
14
+ * +group_by+
15
+
16
+ * Hash
17
+ * <tt>default_proc=</tt>
18
+
3
19
  == Version 1.1 - April 11, 2009
4
20
 
5
21
  * Array
@@ -39,18 +39,25 @@ Works with ruby 1.8 & 1.9
39
39
  * +key+
40
40
  * +symbolize_keys+, <tt>symbolize_keys!</tt>
41
41
  * +reverse_merge+, <tt>reverse_merge!</tt>
42
+ * <tt>default_proc=</tt>
42
43
  * Enumerable
43
44
  * +sum+
44
45
  * +find_index+
45
46
  * +take+, +take_while+, +drop+, +drop_while+
46
47
  * +first+
48
+ * +reverse_each+
49
+ * +count+
50
+ * +cycle+
51
+ * +group_by+
47
52
  * Array
48
53
  * +flatten+, <tt>flatten!</tt>
49
54
  * +find_index+, +find+
55
+ * +reverse_each+
56
+ * +cycle+
50
57
  * Fixnum
51
58
  * <tt>odd?</tt>, <tt>even?</tt>
52
59
 
53
- Finally, there is no need to <tt>require 'enumerator'</tt> in older ruby, and +Enumerator+ can be accessed directly (instead of <tt>Enumerable::Enumerator</p>)
60
+ Finally, there is no need to <tt>require 'enumerator'</tt> in older ruby, and +Enumerator+ can be accessed directly (instead of <tt>Enumerable::Enumerator</tt>)
54
61
 
55
62
  = License
56
63
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 1
4
- :patch: 1
3
+ :minor: 2
4
+ :patch: 0
@@ -10,6 +10,6 @@ module Kernel
10
10
  end unless method_defined? :require_relative
11
11
  end
12
12
 
13
- %w(object module enumerable array string symbol fixnum hash).each do |lib|
13
+ %w(object module array enumerable string symbol fixnum hash).each do |lib|
14
14
  require_relative "backports/#{lib}"
15
15
  end
@@ -56,4 +56,28 @@ class Array
56
56
  alias_method_chain :index, :block
57
57
  alias_method :find_index, :index
58
58
  end
59
+
60
+ # rindex
61
+ unless ([1].rindex{true} rescue false)
62
+ def rindex_with_block(*arg)
63
+ return rindex_without_block(*arg) unless block_given? && arg.empty?
64
+ reverse_each.each_with_index{|o,i| return size - 1 - i if yield o}
65
+ return nil
66
+ end
67
+ alias_method_chain :rindex, :block
68
+ end
69
+
70
+ unless ([1].reverse_each rescue false)
71
+ def reverse_each_with_optional_block(&block)
72
+ return reverse_each_without_optional_block(&block) if block_given?
73
+ to_enum(:reverse_each)
74
+ end
75
+ alias_method_chain :reverse_each, :optional_block
76
+ end
77
+
78
+ def cycle(*arg, &block)
79
+ return to_enum(:cycle, *arg) unless block_given?
80
+ nb = arg.empty? ? (1/0.0) : arg.first
81
+ nb.to_i.times{each(&block)}
82
+ end unless method_defined? :cycle
59
83
  end
@@ -40,7 +40,7 @@ module Enumerable
40
40
 
41
41
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
42
42
  def take_while
43
- raise NotImplemented unless block_given? #todo: what should this do?
43
+ return to_enum(:take_while) unless block_given?
44
44
  inject([]) do |array, elem|
45
45
  return array unless yield elem
46
46
  array << elem
@@ -55,7 +55,7 @@ module Enumerable
55
55
 
56
56
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
57
57
  def drop_while(&block)
58
- raise NotImplemented unless block_given? #todo: what should this do?
58
+ return to_enum(:drop_while) unless block_given?
59
59
  array = to_a
60
60
  array.each_with_index do |element, i|
61
61
  return array.drop(i) unless yield(element)
@@ -68,4 +68,57 @@ module Enumerable
68
68
  arg.empty? ? take(1)[0] : take(arg.first)
69
69
  end unless method_defined? :first
70
70
 
71
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
72
+ def reverse_each(&block)
73
+ return to_enum(:reverse_each) unless block_given?
74
+ # There is no other way then to convert to an array first... see 1.9's source.
75
+ to_a.reverse_each(&block)
76
+ self
77
+ end unless method_defined? :reverse_each
78
+
79
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
80
+ unless ((1..2).each_slice(1) rescue false)
81
+ def each_slice_with_optional_block(len, &block)
82
+ raise ArgumentError, "invalid slice size" if len <= 0
83
+ return to_enum(:each_slice, len) unless block_given?
84
+ each_slice_without_optional_block(len, &block)
85
+ end
86
+ alias_method_chain :each_slice, :optional_block
87
+ end
88
+
89
+ def count(*arg)
90
+ result = 0
91
+ if block_given?
92
+ each{|o| result += 1 if yield o}
93
+ elsif arg.empty?
94
+ each{|o| result += 1}
95
+ else
96
+ obj = arg.first
97
+ each{|o| result += 1 if obj == o}
98
+ end
99
+ result
100
+ end unless method_defined? :count
101
+
102
+ def cycle(*arg, &block)
103
+ return to_enum(:cycle, *arg) unless block_given?
104
+ to_a.cycle(*arg, &block)
105
+ end unless method_defined? :cycle
106
+
107
+ unless ((1..2).each_cons(1) rescue false)
108
+ def each_cons_with_optional_block(len, &block)
109
+ raise ArgumentError, "invalid size" if len <= 0
110
+ return to_enum(:each_cons, len) unless block_given?
111
+ each_cons_without_optional_block(len, &block)
112
+ end
113
+ alias_method_chain :each_cons, :optional_block
114
+ end
115
+
116
+ def group_by
117
+ return to_enum(:group_by) unless block_given?
118
+ returning({}) do |result|
119
+ each do |o|
120
+ result.fetch(yield o){|key| result[key] = []} << o
121
+ end
122
+ end
123
+ end unless method_defined? :group_by
71
124
  end
@@ -34,4 +34,8 @@ class Hash
34
34
  replace(reverse_merge(other_hash))
35
35
  end
36
36
 
37
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
38
+ def default_proc=(proc)
39
+ replace(Hash.new(&proc).merge!(self))
40
+ end unless method_defined? :default_proc=
37
41
  end
@@ -1,63 +1,136 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class BackportsTest < Test::Unit::TestCase
4
- context "find_index" do
5
- should "conform to doc" do
6
- assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
7
- assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
4
+ context "Enumerable" do
5
+ context "#find_index" do
6
+ should "conform to doc" do
7
+ assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
8
+ assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
9
+ end
10
+
11
+ should "#work for enumerables too" do
12
+ assert_equal 69-42, (42..666).find_index(69)
13
+ end
8
14
  end
9
15
 
10
- should "work for enumerables too" do
11
- assert_equal 69-42, (42..666).find_index(69)
16
+ context "#take" do
17
+ should "conform to doc" do
18
+ assert_equal [1, 2, 3], (1..7).take(3)
19
+ assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
20
+ end
21
+
22
+ should "only consume what's needed" do
23
+ assert_equal [], Enumerator.new(nil).take(0)
24
+ assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
25
+ end
12
26
  end
13
- end
27
+
28
+ context "#take_while" do
29
+ should "conform to doc" do
30
+ assert_equal [1,2], (1..7).take_while {|item| item < 3 }
31
+ assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
32
+ end
14
33
 
15
- context "take" do
16
- should "conform to doc" do
17
- assert_equal [1, 2, 3], (1..7).take(3)
18
- assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
34
+ should "work with infinite enumerables" do
35
+ assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
36
+ end
19
37
  end
38
+
39
+ context "#drop" do
40
+ should "conform to doc" do
41
+ assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
42
+ assert_equal [], [ 1, 1, 2, 3, 5, 8, 13 ].drop(99)
43
+ end
20
44
 
21
- should "only consume what's needed" do
22
- assert_equal [], Enumerator.new(nil).take(0)
23
- assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
45
+ should "work with enums" do
46
+ assert_equal [14,15], (10...16).drop(4)
47
+ end
24
48
  end
25
- end
26
49
 
27
- context "take_while" do
28
- should "conform to doc" do
29
- assert_equal [1,2], (1..7).take_while {|item| item < 3 }
30
- assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
50
+ context "#drop_while" do
51
+ should "conform to doc" do
52
+ assert_equal [8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop_while {|item| item < 6 }
53
+ end
54
+
55
+ should "work with enums" do
56
+ assert_equal [14,15], (10...16).drop_while {|item| item < 14}
57
+ end
58
+
59
+ should "work with extemity cases" do
60
+ assert_equal [10,11,12,13,14,15], (10...16).drop_while {|item| false}
61
+ assert_equal [], (10...16).drop_while {|item| true}
62
+ end
63
+ end
64
+
65
+ context "#reverse_each" do
66
+ should "work as expected" do
67
+ assert_equal [4,3,2], (1..4).reverse_each.take(3)
68
+ end
69
+ end
70
+
71
+ context "#each_slice" do
72
+ should "conform to doc" do
73
+ res = []
74
+ (1..10).each_slice(4){|ar| res << ar}
75
+ assert_equal [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10]], res
76
+ assert_equal [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10]], (1..10).each_slice(4).to_a
77
+ end
78
+ end
79
+
80
+ context "#count" do
81
+ should "conform to doc" do
82
+ assert_equal 4, (1..4).count
83
+ assert_equal 1, (1..4).count(3)
84
+ assert_equal 2, (1..4).count{|obj| obj > 2 }
85
+ end
31
86
  end
32
87
 
33
- should "work with infinite enumerables" do
34
- assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
88
+ context "#cycle" do
89
+ should "conform to doc" do
90
+ assert_equal ["a", "b", "c", "a", "b", "c"], ('a'..'c').cycle(2).to_a
91
+ end
35
92
  end
36
- end
37
-
38
- context "drop" do
39
- should "conform to doc" do
40
- assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
41
- assert_equal [], [ 1, 1, 2, 3, 5, 8, 13 ].drop(99)
93
+
94
+ context "#each_cons" do
95
+ should "conform to doc" do
96
+ assert_equal [[1,2],[2,3],[3,4]], (1..4).each_cons(2).to_a
97
+ end
42
98
  end
43
99
 
44
- should "work with enums" do
45
- assert_equal [14,15], (10...16).drop(4)
100
+ context "#group_by" do
101
+ should "conform to doc" do
102
+ x = (1..5).group_by{|item| item.even? ? :even : :odd }
103
+ assert_equal({:even => [2,4], :odd => [1,3,5]}, x)
104
+ assert_equal nil, x[:xyz]
105
+ end
46
106
  end
47
- end
107
+ end #Enumerable
48
108
 
49
- context "drop_while" do
50
- should "conform to doc" do
51
- assert_equal [8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop_while {|item| item < 6 }
109
+ context "Array" do
110
+ context "#reverse_each" do
111
+ should "return an enumerator when no block is given" do
112
+ assert_equal [4,3,2], [1,2,3,4].reverse_each.take(3)
113
+ end
52
114
  end
53
115
 
54
- should "work with enums" do
55
- assert_equal [14,15], (10...16).drop_while {|item| item < 14}
116
+ context "#flatten" do
117
+ should "conform to doc" do
118
+ s = [ 1, 2, 3 ] #=> [1, 2, 3]
119
+ t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
120
+ a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
121
+ assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a.flatten
122
+ a = [ 1, 2, [3, [4, 5] ] ]
123
+ assert_equal [1, 2, 3, [4, 5]], a.flatten(1)
124
+ end
56
125
  end
57
126
 
58
- should "work with extemity cases" do
59
- assert_equal [10,11,12,13,14,15], (10...16).drop_while {|item| false}
60
- assert_equal [], (10...16).drop_while {|item| true}
127
+ context "#index" do
128
+ should "conform to doc" do
129
+ a = [ "a", "b", "c" ]
130
+ assert_equal 1, a.index("b")
131
+ assert_equal nil, a.index("z")
132
+ assert_equal 1, a.index{|x|x=="b"}
133
+ end
61
134
  end
62
135
  end
63
136
 
@@ -65,33 +138,22 @@ class BackportsTest < Test::Unit::TestCase
65
138
  should "should be constructible from key value pairs" do
66
139
  assert_equal({1 => 2, 3 => 4}, Hash[[[1,2],[3,4]]])
67
140
  end
68
- end
69
-
70
- context "flatten" do
71
- should "conform to doc" do
72
- s = [ 1, 2, 3 ] #=> [1, 2, 3]
73
- t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
74
- a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
75
- assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a.flatten
76
- a = [ 1, 2, [3, [4, 5] ] ]
77
- assert_equal [1, 2, 3, [4, 5]], a.flatten(1)
78
- end
79
-
80
- should "conform work for recursive arrays" do
81
- x=[]
82
- x.push(x,x)
83
- 4.times {|n| assert_equal 2 << n, x.flatten(n).length}
84
- assert_raises(ArgumentError) {x.flatten}
85
- end
86
- end
87
-
88
- context "index" do
89
- should "conform to doc" do
90
- a = [ "a", "b", "c" ]
91
- assert_equal 1, a.index("b")
92
- assert_equal nil, a.index("z")
93
- assert_equal 1, a.index{|x|x=="b"}
141
+
142
+ context "#default_proc=" do
143
+ should "conform to doc" do
144
+ h = { :foo => :bar }
145
+ h.default = "Go fish"
146
+ h.default_proc=lambda do |hash, key|
147
+ key + key
148
+ end
149
+ assert_equal :bar, h[:foo]
150
+ assert_equal 4, h[2]
151
+ assert_equal "catcat", h["cat"]
152
+ h.default=nil
153
+ assert_equal nil, h[2]
154
+ assert_equal nil, h["cat"]
155
+ end
94
156
  end
95
157
  end
96
-
158
+
97
159
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backports
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Marc-Andr\xC3\xA9 Lafortune"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-11 00:00:00 -04:00
12
+ date: 2009-04-12 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15