backports 1.1.1 → 1.2.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.
- data/CHANGELOG.rdoc +16 -0
- data/README.rdoc +8 -1
- data/VERSION.yml +2 -2
- data/lib/backports.rb +1 -1
- data/lib/backports/array.rb +24 -0
- data/lib/backports/enumerable.rb +55 -2
- data/lib/backports/hash.rb +4 -0
- data/test/backports_test.rb +127 -65
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
|
@@ -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
|
data/README.rdoc
CHANGED
|
@@ -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</
|
|
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
|
|
data/VERSION.yml
CHANGED
data/lib/backports.rb
CHANGED
|
@@ -10,6 +10,6 @@ module Kernel
|
|
|
10
10
|
end unless method_defined? :require_relative
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
%w(object module enumerable
|
|
13
|
+
%w(object module array enumerable string symbol fixnum hash).each do |lib|
|
|
14
14
|
require_relative "backports/#{lib}"
|
|
15
15
|
end
|
data/lib/backports/array.rb
CHANGED
|
@@ -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
|
data/lib/backports/enumerable.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
data/lib/backports/hash.rb
CHANGED
|
@@ -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
|
data/test/backports_test.rb
CHANGED
|
@@ -1,63 +1,136 @@
|
|
|
1
1
|
require 'test_helper'
|
|
2
2
|
|
|
3
3
|
class BackportsTest < Test::Unit::TestCase
|
|
4
|
-
context "
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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 "
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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.
|
|
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-
|
|
12
|
+
date: 2009-04-12 00:00:00 -04:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|