marcandre-backports 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +21 -0
- data/README.rdoc +6 -16
- data/VERSION.yml +1 -1
- data/lib/backports/array.rb +80 -11
- data/lib/backports/enumerable.rb +176 -64
- data/lib/backports/fixnum.rb +26 -4
- data/lib/backports/hash.rb +5 -0
- data/test/array_test.rb +45 -8
- data/test/enumerable_test.rb +116 -41
- metadata +2 -2
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
= Packable --- History
|
2
2
|
|
3
|
+
== Version 1.5 - April 24, 2009
|
4
|
+
|
5
|
+
* Array (completed)
|
6
|
+
* +combination+
|
7
|
+
* +try_convert+
|
8
|
+
* Optional block for collect!, :map!, :each, :each_index, :reject, :reject!, :delete_if
|
9
|
+
* +pop+, +shift+
|
10
|
+
* +product+
|
11
|
+
|
12
|
+
* Fixnum (completed)
|
13
|
+
* +div+, +fdiv+
|
14
|
+
* +succ+
|
15
|
+
* +magnitude+
|
16
|
+
|
17
|
+
* Enumerable (completed)
|
18
|
+
* +each_with_object+
|
19
|
+
* +inject+
|
20
|
+
* +max_by+, +min_by+, +minmax+, +minmax_by+
|
21
|
+
* +reduce+
|
22
|
+
* +to_a+
|
23
|
+
|
3
24
|
== Version 1.4 - April 21, 2009
|
4
25
|
|
5
26
|
* String
|
data/README.rdoc
CHANGED
@@ -47,29 +47,19 @@ Compatible with Ruby 1.8 & 1.9.
|
|
47
47
|
* +constantize+
|
48
48
|
* +partition+, +rpartition+
|
49
49
|
* Hash
|
50
|
-
* <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
|
51
|
-
* +key+
|
52
50
|
* +symbolize_keys+, <tt>symbolize_keys!</tt>
|
53
51
|
* +reverse_merge+, <tt>reverse_merge!</tt>
|
52
|
+
* <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
|
53
|
+
* +key+
|
54
54
|
* <tt>default_proc=</tt>
|
55
55
|
* Enumerable
|
56
56
|
* +sum+
|
57
|
-
*
|
58
|
-
* +take+, +take_while+, +drop+, +drop_while+
|
59
|
-
* +first+
|
60
|
-
* +reverse_each+
|
61
|
-
* +count+
|
62
|
-
* +cycle+
|
63
|
-
* +group_by+
|
64
|
-
* <tt>none?</tt>
|
57
|
+
* complete Ruby 1.8.7 backport
|
65
58
|
* Array
|
66
|
-
*
|
67
|
-
* +find_index+, +find+
|
68
|
-
* +reverse_each+
|
69
|
-
* +cycle+
|
59
|
+
* complete Ruby 1.8.7 backport
|
70
60
|
* Fixnum
|
71
|
-
*
|
72
|
-
*
|
61
|
+
* complete Ruby 1.8.7 backport
|
62
|
+
* Proc
|
73
63
|
* +yield+
|
74
64
|
|
75
65
|
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>)
|
data/VERSION.yml
CHANGED
data/lib/backports/array.rb
CHANGED
@@ -1,4 +1,52 @@
|
|
1
1
|
class Array
|
2
|
+
class << self
|
3
|
+
# Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
4
|
+
def try_convert(x)
|
5
|
+
x.to_ary if x.respond_to? :to_ary
|
6
|
+
end unless method_defined? :try_convert
|
7
|
+
end
|
8
|
+
|
9
|
+
# Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
10
|
+
unless ([42].map! rescue false)
|
11
|
+
# Make block optional for...
|
12
|
+
[:collect!, :map!, :each, :each_index, :reverse_each, :reject, :reject!, :delete_if].each do |selector|
|
13
|
+
alias_method_chain(selector, :optional_block) do |aliased_target, punctuation|
|
14
|
+
module_eval <<-end_eval
|
15
|
+
def #{aliased_target}_with_optional_block#{punctuation}(*args, &block)
|
16
|
+
return to_enum(:#{aliased_target}_without_optional_block#{punctuation}, *args) unless block_given?
|
17
|
+
#{aliased_target}_without_optional_block#{punctuation}(*args, &block)
|
18
|
+
end
|
19
|
+
end_eval
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
25
|
+
def combination(num)
|
26
|
+
num = num.to_i
|
27
|
+
return to_enum(:combination, num) unless block_given?
|
28
|
+
return self unless (0..size).include? num
|
29
|
+
# Implementation note: slightly tricky.
|
30
|
+
# Example: self = 1..7, num = 3
|
31
|
+
picks = (0...num).to_a # picks start at 0, 1, 2
|
32
|
+
max = ((size-num)...size).to_a # max (index for a given pick) is [4, 5, 6]
|
33
|
+
pick_max_pairs = picks.zip(max).reverse # pick_max_pairs = [[2, 6], [1, 5], [0, 4]]
|
34
|
+
lookup = pick_max_pairs.find(Proc.new{return self})
|
35
|
+
loop do
|
36
|
+
yield values_at(*picks)
|
37
|
+
move = lookup.each{|pick, max| picks[pick] < max}.first
|
38
|
+
new_index = picks[move] + 1
|
39
|
+
picks[move...num] = (new_index...(new_index+num-move)).to_a
|
40
|
+
end
|
41
|
+
end unless method_defined? :combination
|
42
|
+
|
43
|
+
# Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
44
|
+
def cycle(*arg, &block)
|
45
|
+
return to_enum(:cycle, *arg) unless block_given?
|
46
|
+
nb = arg.empty? ? (1/0.0) : arg.first
|
47
|
+
nb.to_i.times{each(&block)}
|
48
|
+
end unless method_defined? :cycle
|
49
|
+
|
2
50
|
# flatten & flatten!, standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
3
51
|
unless ([[]].flatten(1) rescue false)
|
4
52
|
|
@@ -57,6 +105,30 @@ class Array
|
|
57
105
|
alias_method :find_index, :index
|
58
106
|
end
|
59
107
|
|
108
|
+
# pop. Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
109
|
+
unless ([1].pop(1) rescue false)
|
110
|
+
def pop_with_optional_argument(*arg)
|
111
|
+
return pop_without_optional_argument if arg.empty?
|
112
|
+
n = arg.first.to_i
|
113
|
+
slice!([0,size-n].max, size)
|
114
|
+
end
|
115
|
+
alias_method_chain :pop, :optional_argument
|
116
|
+
end
|
117
|
+
|
118
|
+
def product(*arg)
|
119
|
+
arg.unshift(self)
|
120
|
+
arg._partial_cartesian_product(arg.size-1, Array.new(arg.size), [])
|
121
|
+
end unless method_defined? :product
|
122
|
+
|
123
|
+
def _partial_cartesian_product(combi, iterate_index, result)
|
124
|
+
action = iterate_index.zero? ? Proc.new(result << combi.dup) : Proc.new(_sub(combi, iterate_index-1, &block))
|
125
|
+
self[iterate_index].each do |obj|
|
126
|
+
combi[iterate_index] = obj
|
127
|
+
action.call
|
128
|
+
end
|
129
|
+
end
|
130
|
+
private :_partial_cartesian_product
|
131
|
+
|
60
132
|
# rindex
|
61
133
|
unless ([1].rindex{true} rescue false)
|
62
134
|
def rindex_with_block(*arg)
|
@@ -66,20 +138,17 @@ class Array
|
|
66
138
|
end
|
67
139
|
alias_method_chain :rindex, :block
|
68
140
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
141
|
+
|
142
|
+
# shift. Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
|
143
|
+
unless ([1].shift(1) rescue false)
|
144
|
+
def shift_with_optional_argument(*arg)
|
145
|
+
return shift_without_optional_argument if arg.empty?
|
146
|
+
n = arg.first.to_i
|
147
|
+
slice!(0, n)
|
74
148
|
end
|
75
|
-
alias_method_chain :
|
149
|
+
alias_method_chain :shift, :optional_argument
|
76
150
|
end
|
77
151
|
|
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
|
83
152
|
|
84
153
|
def sample(*arg)
|
85
154
|
return self[rand(size)] if arg.empty?
|
data/lib/backports/enumerable.rb
CHANGED
@@ -10,42 +10,35 @@ module Enumerable
|
|
10
10
|
end unless method_defined? :sum
|
11
11
|
|
12
12
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
elsif block_given?
|
20
|
-
each_with_index do |element, i|
|
21
|
-
return i if yield element
|
22
|
-
end
|
23
|
-
each_with_index{|o,i| return i if yield o}
|
13
|
+
def count(*arg)
|
14
|
+
result = 0
|
15
|
+
if block_given?
|
16
|
+
each{|o| result += 1 if yield o}
|
17
|
+
elsif arg.empty?
|
18
|
+
each{|o| result += 1}
|
24
19
|
else
|
25
|
-
|
20
|
+
obj = arg.first
|
21
|
+
each{|o| result += 1 if obj == o}
|
26
22
|
end
|
27
|
-
|
28
|
-
end unless method_defined? :
|
23
|
+
result
|
24
|
+
end unless method_defined? :count
|
29
25
|
|
30
26
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
break if array.size >= n
|
36
|
-
end unless n <= 0
|
37
|
-
end
|
38
|
-
end unless method_defined? :take
|
27
|
+
def cycle(*arg, &block)
|
28
|
+
return to_enum(:cycle, *arg) unless block_given?
|
29
|
+
to_a.cycle(*arg, &block)
|
30
|
+
end unless method_defined? :cycle
|
39
31
|
|
40
32
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
array << elem
|
33
|
+
unless ([].detect rescue false)
|
34
|
+
def detect_with_optional_block(ifnone = nil, &block)
|
35
|
+
return to_enum(:detect, ifnone) unless block_given?
|
36
|
+
detect_without_optional_block(ifnone, &block)
|
46
37
|
end
|
47
|
-
|
48
|
-
|
38
|
+
alias_method_chain :detect, :optional_block
|
39
|
+
alias_method :find, :detect
|
40
|
+
end
|
41
|
+
|
49
42
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
50
43
|
def drop(n)
|
51
44
|
array = to_a
|
@@ -63,18 +56,15 @@ module Enumerable
|
|
63
56
|
end unless method_defined? :drop_while
|
64
57
|
|
65
58
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
unless ((1..2).each_cons(1) rescue false)
|
60
|
+
def each_cons_with_optional_block(len, &block)
|
61
|
+
raise ArgumentError, "invalid size" if len <= 0
|
62
|
+
return to_enum(:each_cons, len) unless block_given?
|
63
|
+
each_cons_without_optional_block(len, &block)
|
64
|
+
end
|
65
|
+
alias_method_chain :each_cons, :optional_block
|
66
|
+
end
|
69
67
|
|
70
|
-
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
71
|
-
def reverse_each(&block)
|
72
|
-
return to_enum(:reverse_each) unless block_given?
|
73
|
-
# There is no other way then to convert to an array first... see 1.9's source.
|
74
|
-
to_a.reverse_each(&block)
|
75
|
-
self
|
76
|
-
end unless method_defined? :reverse_each
|
77
|
-
|
78
68
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
79
69
|
unless ((1..2).each_slice(1) rescue false)
|
80
70
|
def each_slice_with_optional_block(len, &block)
|
@@ -84,36 +74,45 @@ module Enumerable
|
|
84
74
|
end
|
85
75
|
alias_method_chain :each_slice, :optional_block
|
86
76
|
end
|
87
|
-
|
77
|
+
|
88
78
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
each
|
93
|
-
elsif arg.empty?
|
94
|
-
each{|o| result += 1}
|
95
|
-
else
|
96
|
-
obj = arg.first
|
97
|
-
each{|o| result += 1 if obj == o}
|
79
|
+
if instance_method(:each_with_index).arity.zero?
|
80
|
+
def each_with_index_with_optional_args_and_block(*args, &block)
|
81
|
+
return to_enum(:each_with_index, *args) unless block_given?
|
82
|
+
to_enum(:each, *args).each_with_index_without_optional_args_and_block(&block)
|
98
83
|
end
|
99
|
-
|
100
|
-
end
|
84
|
+
alias_method_chain :each_with_index, :optional_args_and_block
|
85
|
+
end
|
101
86
|
|
102
87
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
103
|
-
def
|
104
|
-
return to_enum(:
|
105
|
-
|
106
|
-
|
107
|
-
|
88
|
+
def each_with_object(memo, &block)
|
89
|
+
return to_enum(:each_with_object, memo) unless block_given?
|
90
|
+
each {|obj| block.call(obj, memo)}
|
91
|
+
memo
|
92
|
+
end unless method_defined? :each_with_object
|
93
|
+
|
108
94
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
95
|
+
def find_index(*args)
|
96
|
+
if args.size == 1
|
97
|
+
obj = args.first
|
98
|
+
each_with_index do |element, i|
|
99
|
+
return i if element == obj
|
100
|
+
end
|
101
|
+
elsif block_given?
|
102
|
+
each_with_index do |element, i|
|
103
|
+
return i if yield element
|
104
|
+
end
|
105
|
+
each_with_index{|o,i| return i if yield o}
|
106
|
+
else
|
107
|
+
raise ArgumentError, "Wrong number of arguments (#{args.size} for 1)"
|
114
108
|
end
|
115
|
-
|
116
|
-
end
|
109
|
+
nil
|
110
|
+
end unless method_defined? :find_index
|
111
|
+
|
112
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
113
|
+
def first(*arg)
|
114
|
+
arg.empty? ? take(1)[0] : take(arg.first)
|
115
|
+
end unless method_defined? :first
|
117
116
|
|
118
117
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
119
118
|
def group_by
|
@@ -125,9 +124,122 @@ module Enumerable
|
|
125
124
|
end
|
126
125
|
end unless method_defined? :group_by
|
127
126
|
|
127
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
128
|
+
unless ((1..2).inject(:+) rescue false)
|
129
|
+
def inject_with_symbol(*args, &block)
|
130
|
+
return inject_without_symbol(*args, &block) if block_given?
|
131
|
+
method = args.pop
|
132
|
+
raise TypeError, "#{method} is not a symbol" unless method.respond_to? :to_sym
|
133
|
+
method = method.to_sym
|
134
|
+
inject_without_symbol(*args) {|memo, obj| memo.send(method, obj)}
|
135
|
+
end
|
136
|
+
alias_method_chain :inject, :symbol
|
137
|
+
end
|
138
|
+
|
139
|
+
MOST_EXTREME_OBJECT_EVER = Object.new # :nodoc:
|
140
|
+
class << MOST_EXTREME_OBJECT_EVER
|
141
|
+
def < (whatever)
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
def > (whatever)
|
146
|
+
true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
151
|
+
def max_by(&block)
|
152
|
+
return to_enum(:max_by) unless block_given?
|
153
|
+
minmax_by(&block)[1]
|
154
|
+
end unless method_defined? :max_by
|
155
|
+
|
156
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
157
|
+
def min_by(&block)
|
158
|
+
return to_enum(:min_by) unless block_given?
|
159
|
+
minmax_by(&block).first
|
160
|
+
end unless method_defined? :min_by
|
161
|
+
|
162
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
163
|
+
def minmax
|
164
|
+
return minmax{|a,b| a <=> b} unless block_given?
|
165
|
+
first_time = true
|
166
|
+
min, max = nil
|
167
|
+
each do |object|
|
168
|
+
if first_time
|
169
|
+
min = max = object
|
170
|
+
first_time = false
|
171
|
+
else
|
172
|
+
min = object if yield(min, object) > 0
|
173
|
+
max = object if yield(max, object) < 0
|
174
|
+
end
|
175
|
+
end
|
176
|
+
[min, max]
|
177
|
+
end unless method_defined? :minmax
|
178
|
+
|
179
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
180
|
+
def minmax_by(&block)
|
181
|
+
return to_enum(:minmax_by) unless block_given?
|
182
|
+
min_object, min_result = nil, MOST_EXTREME_OBJECT_EVER
|
183
|
+
max_object, max_result = nil, MOST_EXTREME_OBJECT_EVER
|
184
|
+
each do |object|
|
185
|
+
result = yield object
|
186
|
+
min_object, min_result = object, result if min_result > result
|
187
|
+
max_object, max_result = object, result if max_result < result
|
188
|
+
end
|
189
|
+
[min_object, max_object]
|
190
|
+
end unless method_defined? :minmax_by
|
191
|
+
|
128
192
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
129
193
|
def none?(&block)
|
130
194
|
!any?(&block)
|
131
195
|
end unless method_defined? :none?
|
132
196
|
|
197
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
198
|
+
def one?(&block)
|
199
|
+
return one?{|o| o} unless block_given?
|
200
|
+
1 == count(&block)
|
201
|
+
end unless method_defined? :one?
|
202
|
+
|
203
|
+
alias_method :reduce, :inject unless method_defined? :reduce
|
204
|
+
|
205
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
206
|
+
def reverse_each(&block)
|
207
|
+
return to_enum(:reverse_each) unless block_given?
|
208
|
+
# There is no other way then to convert to an array first... see 1.9's source.
|
209
|
+
to_a.reverse_each(&block)
|
210
|
+
self
|
211
|
+
end unless method_defined? :reverse_each
|
212
|
+
|
213
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
214
|
+
def take(n)
|
215
|
+
returning([]) do |array|
|
216
|
+
each do |elem|
|
217
|
+
array << elem
|
218
|
+
break if array.size >= n
|
219
|
+
end unless n <= 0
|
220
|
+
end
|
221
|
+
end unless method_defined? :take
|
222
|
+
|
223
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
224
|
+
def take_while
|
225
|
+
return to_enum(:take_while) unless block_given?
|
226
|
+
inject([]) do |array, elem|
|
227
|
+
return array unless yield elem
|
228
|
+
array << elem
|
229
|
+
end
|
230
|
+
end unless method_defined? :take_while
|
231
|
+
|
232
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
233
|
+
if instance_method(:to_a).arity.zero?
|
234
|
+
def to_a_with_optional_arguments(*args)
|
235
|
+
return to_a_without_optional_arguments if args.empty?
|
236
|
+
to_enum(:each, *args).to_a
|
237
|
+
end
|
238
|
+
alias_method_chain :to_a, :optional_arguments
|
239
|
+
end
|
240
|
+
|
133
241
|
end
|
242
|
+
|
243
|
+
class Enumerator
|
244
|
+
alias_method :with_object, :each_with_object unless method_defined? :with_object
|
245
|
+
end
|
data/lib/backports/fixnum.rb
CHANGED
@@ -1,11 +1,33 @@
|
|
1
1
|
class Fixnum
|
2
2
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
3
|
-
def
|
4
|
-
self
|
5
|
-
end unless method_defined? :
|
6
|
-
|
3
|
+
def div(n)
|
4
|
+
(self / n).round
|
5
|
+
end unless method_defined? :div
|
6
|
+
|
7
7
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
8
8
|
def even?
|
9
9
|
self & 1 == 0
|
10
10
|
end unless method_defined? :even?
|
11
|
+
|
12
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
13
|
+
def fdiv(n)
|
14
|
+
to_f / n
|
15
|
+
end unless method_defined? :fdiv
|
16
|
+
|
17
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
18
|
+
def odd?
|
19
|
+
self & 1 == 1
|
20
|
+
end unless method_defined? :odd?
|
21
|
+
|
22
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
23
|
+
def succ
|
24
|
+
self + 1
|
25
|
+
end unless method_defined? :succ
|
26
|
+
|
27
|
+
alias_method :magnitude, :abs unless method_defined? :magnitude
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
11
33
|
end
|
data/lib/backports/hash.rb
CHANGED
@@ -9,6 +9,11 @@ class Hash
|
|
9
9
|
arg.first.each{|key, value| h[key] = value}
|
10
10
|
end
|
11
11
|
end unless (Hash[[[:test, :test]]] rescue false)
|
12
|
+
|
13
|
+
def try_convert(x)
|
14
|
+
return nil unless x.respond_to? :to_hash
|
15
|
+
x.to_hash
|
16
|
+
end unless method_defined? :to_hash
|
12
17
|
end
|
13
18
|
|
14
19
|
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
|
data/test/array_test.rb
CHANGED
@@ -2,17 +2,21 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class ArrayTest < Test::Unit::TestCase
|
4
4
|
context "Array" do
|
5
|
-
context "#
|
6
|
-
should "
|
7
|
-
|
5
|
+
context "#combination" do
|
6
|
+
should "conform to doc" do
|
7
|
+
a = [ "a", "b", "c" ]
|
8
|
+
assert_equal [["a"], ["b"], ["c"]], a.combination(1).to_a
|
9
|
+
assert_equal [["a", "b"], ["a", "c"], ["b", "c"]], a.combination(2).to_a
|
10
|
+
assert_equal [["a", "b", "c"]], a.combination(3).to_a
|
11
|
+
assert_equal [], a.combination(4).to_a
|
8
12
|
end
|
9
13
|
end
|
10
|
-
|
14
|
+
|
11
15
|
context "#flatten" do
|
12
16
|
should "conform to doc" do
|
13
|
-
s = [ 1, 2, 3 ]
|
14
|
-
t = [ 4, 5, 6, [7, 8] ]
|
15
|
-
a = [ s, t, 9, 10 ]
|
17
|
+
s = [ 1, 2, 3 ]
|
18
|
+
t = [ 4, 5, 6, [7, 8] ]
|
19
|
+
a = [ s, t, 9, 10 ]
|
16
20
|
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a.flatten
|
17
21
|
a = [ 1, 2, [3, [4, 5] ] ]
|
18
22
|
assert_equal [1, 2, 3, [4, 5]], a.flatten(1)
|
@@ -28,6 +32,30 @@ class ArrayTest < Test::Unit::TestCase
|
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
35
|
+
context "#reverse_each" do
|
36
|
+
should "return an enumerator when no block is given" do
|
37
|
+
assert_equal [4,3,2], [1,2,3,4].reverse_each.take(3)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "#pop" do
|
42
|
+
should "conform to doc" do
|
43
|
+
a = %w{ f r a b j o u s }
|
44
|
+
assert_equal "s", a.pop
|
45
|
+
assert_equal ["f", "r", "a", "b", "j", "o", "u"] , a
|
46
|
+
assert_equal ["j", "o", "u"], a.pop(3)
|
47
|
+
assert_equal ["f", "r", "a", "b"] , a
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "#product" do
|
52
|
+
should "conform to doc" do
|
53
|
+
assert_equal [[1, 3], [1, 4], [2, 3], [2, 4]], [1, 2].product([3, 4])
|
54
|
+
assert_equal [[1, 3, 5], [1, 4, 5], [2, 3, 5], [2, 4, 5]], [1, 2].product([3, 4], [5])
|
55
|
+
assert_equal [[1], [2]], [1, 2].product
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
31
59
|
context "#sample" do
|
32
60
|
should "conform to doc" do
|
33
61
|
assert_equal nil, [].sample
|
@@ -38,7 +66,16 @@ class ArrayTest < Test::Unit::TestCase
|
|
38
66
|
s = a.sample(2)
|
39
67
|
assert_equal 2, s.size
|
40
68
|
assert_equal 1, (a-s).size
|
41
|
-
assert_equal [], a-(0..20).sum{a.sample(2)}
|
69
|
+
assert_equal [], a-(0..20).sum{a.sample(2)}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#shift" do
|
74
|
+
should "conform to doc" do
|
75
|
+
args = [ "-m", "-q", "-v", "filename" ]
|
76
|
+
assert_equal "-m", args.shift
|
77
|
+
assert_equal ["-q", "-v"], args.shift(2)
|
78
|
+
assert_equal ["filename"], args
|
42
79
|
end
|
43
80
|
end
|
44
81
|
end
|
data/test/enumerable_test.rb
CHANGED
@@ -1,41 +1,22 @@
|
|
1
1
|
require 'test_helper'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
class EnumerableTest < Test::Unit::TestCase
|
4
5
|
context "Enumerable" do
|
5
|
-
context "#
|
6
|
+
context "#count" do
|
6
7
|
should "conform to doc" do
|
7
|
-
assert_equal
|
8
|
-
assert_equal
|
9
|
-
|
10
|
-
|
11
|
-
should "#work for enumerables too" do
|
12
|
-
assert_equal 69-42, (42..666).find_index(69)
|
8
|
+
assert_equal 4, (1..4).count
|
9
|
+
assert_equal 1, (1..4).count(3)
|
10
|
+
assert_equal 2, (1..4).count{|obj| obj > 2 }
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
16
|
-
context "#
|
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
|
26
|
-
end
|
27
|
-
|
28
|
-
context "#take_while" do
|
14
|
+
context "#cycle" do
|
29
15
|
should "conform to doc" do
|
30
|
-
assert_equal [
|
31
|
-
assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
|
32
|
-
end
|
33
|
-
|
34
|
-
should "work with infinite enumerables" do
|
35
|
-
assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
|
16
|
+
assert_equal ["a", "b", "c", "a", "b", "c"], ('a'..'c').cycle(2).to_a
|
36
17
|
end
|
37
18
|
end
|
38
|
-
|
19
|
+
|
39
20
|
context "#drop" do
|
40
21
|
should "conform to doc" do
|
41
22
|
assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
|
@@ -62,9 +43,9 @@ class EnumerableTest < Test::Unit::TestCase
|
|
62
43
|
end
|
63
44
|
end
|
64
45
|
|
65
|
-
context "#
|
66
|
-
should "
|
67
|
-
assert_equal [
|
46
|
+
context "#each_cons" do
|
47
|
+
should "conform to doc" do
|
48
|
+
assert_equal [[1,2],[2,3],[3,4]], (1..4).each_cons(2).to_a
|
68
49
|
end
|
69
50
|
end
|
70
51
|
|
@@ -76,27 +57,43 @@ class EnumerableTest < Test::Unit::TestCase
|
|
76
57
|
assert_equal [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10]], (1..10).each_slice(4).to_a
|
77
58
|
end
|
78
59
|
end
|
79
|
-
|
80
|
-
context "#
|
60
|
+
|
61
|
+
context "#each_with_index" do
|
81
62
|
should "conform to doc" do
|
82
|
-
|
83
|
-
|
84
|
-
|
63
|
+
hash = Hash.new
|
64
|
+
%w(cat dog wombat).each_with_index do |item, index|
|
65
|
+
hash[item] = index
|
66
|
+
end
|
67
|
+
assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
|
85
68
|
end
|
69
|
+
|
70
|
+
should "be ok with arguments and no block" do
|
71
|
+
s = StringIO.new("Hello world!")
|
72
|
+
assert_equal [["Hello",0], [" wo",1], ["rld!",2]], s.each_with_index("o").to_a
|
73
|
+
end
|
74
|
+
|
86
75
|
end
|
87
76
|
|
88
|
-
context "#
|
77
|
+
context "#each_with_object" do
|
89
78
|
should "conform to doc" do
|
90
|
-
|
79
|
+
hash = %w(cat dog wombat).each_with_object({}) do |item, memo|
|
80
|
+
memo[item] = item.upcase.reverse
|
81
|
+
end
|
82
|
+
assert_equal({"cat"=>"TAC", "dog"=>"GOD", "wombat"=>"TABMOW"}, hash)
|
91
83
|
end
|
92
84
|
end
|
93
|
-
|
94
|
-
context "#
|
85
|
+
|
86
|
+
context "#find_index" do
|
95
87
|
should "conform to doc" do
|
96
|
-
assert_equal
|
88
|
+
assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
|
89
|
+
assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
|
90
|
+
end
|
91
|
+
|
92
|
+
should "#work for enumerables too" do
|
93
|
+
assert_equal 69-42, (42..666).find_index(69)
|
97
94
|
end
|
98
95
|
end
|
99
|
-
|
96
|
+
|
100
97
|
context "#group_by" do
|
101
98
|
should "conform to doc" do
|
102
99
|
x = (1..5).group_by{|item| item.even? ? :even : :odd }
|
@@ -104,5 +101,83 @@ class EnumerableTest < Test::Unit::TestCase
|
|
104
101
|
assert_equal nil, x[:xyz]
|
105
102
|
end
|
106
103
|
end
|
104
|
+
|
105
|
+
context "#inject" do
|
106
|
+
should "conform to doc" do
|
107
|
+
assert_equal 45, (5..10).inject(0) {|sum, n| sum + n }
|
108
|
+
assert_equal 45, (5..10).inject {|sum, n| sum + n }
|
109
|
+
assert_equal 45, (5..10).inject(0, :+)
|
110
|
+
assert_equal 45, (5..10).inject(:+)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "#max_by" do
|
115
|
+
should "conform to doc" do
|
116
|
+
a = %w(albatross dog horse fox)
|
117
|
+
assert_equal "albatross" , a.max_by {|item| item.length }
|
118
|
+
assert_equal "fox", a.max_by {|item| item.reverse }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "#min_by" do
|
123
|
+
should "conform to doc" do
|
124
|
+
a = %w(albatross dog horse fox)
|
125
|
+
assert_equal "dog" , a.min_by {|item| item.length }
|
126
|
+
assert_equal "horse", a.min_by {|item| item.reverse }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "#minmax" do
|
131
|
+
should "conform to doc" do
|
132
|
+
a = %w(albatross dog horse)
|
133
|
+
assert_equal ["albatross", "horse"], a.minmax
|
134
|
+
assert_equal ["dog", "albatross"], a.minmax {|a,b| a.length <=> b.length }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "#one" do
|
139
|
+
should "conform to doc" do
|
140
|
+
assert_equal false, %w{ ant bear cat}.one? {|word| word.length >= 3}
|
141
|
+
assert_equal true, %w{ ant bear cat}.one? {|word| word.length >= 4}
|
142
|
+
assert_equal true, [ nil, nil, 99 ].one?
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "#reverse_each" do
|
147
|
+
should "work as expected" do
|
148
|
+
assert_equal [4,3,2], (1..4).reverse_each.take(3)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "#take" do
|
153
|
+
should "conform to doc" do
|
154
|
+
assert_equal [1, 2, 3], (1..7).take(3)
|
155
|
+
assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
|
156
|
+
end
|
157
|
+
|
158
|
+
should "only consume what's needed" do
|
159
|
+
assert_equal [], Enumerator.new(nil).take(0)
|
160
|
+
assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "#take_while" do
|
165
|
+
should "conform to doc" do
|
166
|
+
assert_equal [1,2], (1..7).take_while {|item| item < 3 }
|
167
|
+
assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
|
168
|
+
end
|
169
|
+
|
170
|
+
should "work with infinite enumerables" do
|
171
|
+
assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "#to_a" do
|
176
|
+
should "work with arguments" do
|
177
|
+
s = StringIO.new("Hello world!")
|
178
|
+
assert_equal ["Hello", " wo", "rld!"], s.to_a("o")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
107
182
|
end
|
108
183
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marcandre-backports
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.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-24 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|