backports 1.3.1 → 1.5.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 +29 -0
- data/README.rdoc +7 -15
- data/VERSION.yml +2 -2
- data/lib/backports.rb +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/lib/backports/proc.rb +4 -0
- data/test/array_test.rb +45 -8
- data/test/enumerable_test.rb +116 -41
- metadata +3 -2
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,34 @@
|
|
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
|
+
|
24
|
+
== Version 1.4 - April 21, 2009
|
25
|
+
|
26
|
+
* String
|
27
|
+
* +rpartition+
|
28
|
+
|
29
|
+
* Proc
|
30
|
+
* +yield+
|
31
|
+
|
3
32
|
== Version 1.3 - April 17, 2009
|
4
33
|
|
5
34
|
* Enumerable
|
data/README.rdoc
CHANGED
@@ -47,28 +47,20 @@ 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
|
-
*
|
61
|
+
* complete Ruby 1.8.7 backport
|
62
|
+
* Proc
|
63
|
+
* +yield+
|
72
64
|
|
73
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>)
|
74
66
|
|
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 array enumerable string symbol fixnum hash).each do |lib|
|
13
|
+
%w(object module array enumerable string symbol fixnum hash proc).each do |lib|
|
14
14
|
require_relative "backports/#{lib}"
|
15
15
|
end
|
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: 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 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- lib/backports/hash.rb
|
36
36
|
- lib/backports/module.rb
|
37
37
|
- lib/backports/object.rb
|
38
|
+
- lib/backports/proc.rb
|
38
39
|
- lib/backports/string.rb
|
39
40
|
- lib/backports/symbol.rb
|
40
41
|
- test/array_test.rb
|