backports 1.2.0 → 1.3.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 +14 -0
- data/README.rdoc +23 -8
- data/VERSION.yml +1 -1
- data/lib/backports/array.rb +20 -0
- data/lib/backports/enumerable.rb +14 -5
- data/lib/backports/string.rb +42 -6
- data/test/array_test.rb +45 -0
- data/test/{backports_test.rb → enumerable_test.rb} +2 -53
- data/test/hash_test.rb +26 -0
- data/test/string_test.rb +40 -0
- metadata +10 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
= Packable --- History
|
2
2
|
|
3
|
+
== Version 1.3 - April 17, 2009
|
4
|
+
|
5
|
+
* Enumerable
|
6
|
+
* <tt>none?</tt>
|
7
|
+
|
8
|
+
* Array
|
9
|
+
* +sample+, +shuffle+, +shuffle!+
|
10
|
+
|
11
|
+
* String
|
12
|
+
* +each_char+, +chars+
|
13
|
+
* +partition+
|
14
|
+
|
15
|
+
Tests and fixes for <tt>String#start_with?</tt> and <tt>String#end_with?</tt>
|
16
|
+
|
3
17
|
== Version 1.2 - April 12, 2009
|
4
18
|
|
5
19
|
* Array
|
data/README.rdoc
CHANGED
@@ -1,22 +1,32 @@
|
|
1
1
|
= Backports Library
|
2
2
|
|
3
|
-
Essential backports that make it possible to use some of the really nice features of
|
3
|
+
Essential backports that make it possible to use some of the really nice features of Ruby 1.8.7, Ruby 1.9 and rails from Ruby 1.8.x
|
4
4
|
|
5
5
|
Conditions for inclusion:
|
6
|
-
1. Standard in either
|
6
|
+
1. Standard in either Ruby or Rails
|
7
7
|
2. Won't break older code
|
8
8
|
3. Simple and self-contained
|
9
9
|
|
10
10
|
The first and second rules avoids conflicts in future and the past respectively. Because of the second rule, incompatibilities between 1.8 and 1.9 methods are left alone.
|
11
11
|
For example, <tt>Module::instance_methods</tt> returns strings in 1.8 and symbols in 1.9; no change can be made without the risk of breaking existing code.
|
12
12
|
|
13
|
-
More complex features of
|
13
|
+
More complex features of active-support (even things like <tt>String::pluralize</tt>), won't be included. <tt>require 'activesupport'</tt> if you need them and are not in rails!
|
14
14
|
|
15
|
-
I've added
|
15
|
+
I've added these backports as I need them; pull requests welcome (with tests for Ruby 1.9 backports)
|
16
16
|
|
17
|
-
==
|
17
|
+
== Installation & compatibility
|
18
18
|
|
19
|
-
|
19
|
+
+backports+ is mirrored on Rubyforge and can thus be installed with:
|
20
|
+
|
21
|
+
sudo gem install backports
|
22
|
+
|
23
|
+
To use:
|
24
|
+
|
25
|
+
require 'rubygems'
|
26
|
+
require 'backports'
|
27
|
+
# and off you go!
|
28
|
+
|
29
|
+
Compatible with Ruby 1.8 & 1.9.
|
20
30
|
|
21
31
|
= List of backports
|
22
32
|
|
@@ -30,12 +40,14 @@ Works with ruby 1.8 & 1.9
|
|
30
40
|
* +tap+, +returning+
|
31
41
|
* +try+
|
32
42
|
* String
|
43
|
+
* +each_char+, +chars+
|
33
44
|
* <tt>start_with?</tt>, <tt>end_with?</tt>
|
34
45
|
* +camelize+, +underscore+
|
35
46
|
* +dasherize+, +demodulize+
|
36
47
|
* +constantize+
|
48
|
+
* +partition+
|
37
49
|
* Hash
|
38
|
-
* <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt>
|
50
|
+
* <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
|
39
51
|
* +key+
|
40
52
|
* +symbolize_keys+, <tt>symbolize_keys!</tt>
|
41
53
|
* +reverse_merge+, <tt>reverse_merge!</tt>
|
@@ -49,6 +61,7 @@ Works with ruby 1.8 & 1.9
|
|
49
61
|
* +count+
|
50
62
|
* +cycle+
|
51
63
|
* +group_by+
|
64
|
+
* <tt>none?</tt>
|
52
65
|
* Array
|
53
66
|
* +flatten+, <tt>flatten!</tt>
|
54
67
|
* +find_index+, +find+
|
@@ -57,7 +70,9 @@ Works with ruby 1.8 & 1.9
|
|
57
70
|
* Fixnum
|
58
71
|
* <tt>odd?</tt>, <tt>even?</tt>
|
59
72
|
|
60
|
-
Finally, there is no need to <tt>require 'enumerator'</tt> in older
|
73
|
+
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
|
+
|
75
|
+
_note_: This usage of <tt>Hash::[]</tt> is not yet documented[http://redmine.ruby-lang.org/issues/show/1385].
|
61
76
|
|
62
77
|
= License
|
63
78
|
|
data/VERSION.yml
CHANGED
data/lib/backports/array.rb
CHANGED
@@ -80,4 +80,24 @@ class Array
|
|
80
80
|
nb = arg.empty? ? (1/0.0) : arg.first
|
81
81
|
nb.to_i.times{each(&block)}
|
82
82
|
end unless method_defined? :cycle
|
83
|
+
|
84
|
+
def sample(*arg)
|
85
|
+
return self[rand(size)] if arg.empty?
|
86
|
+
n = [arg.first.to_i, size].min
|
87
|
+
index = Array.new(size)
|
88
|
+
n.times do |i|
|
89
|
+
r = i + rand(size - i)
|
90
|
+
index[i], index[r] = index[r] || r, index[i] || i
|
91
|
+
end
|
92
|
+
values_at(*index.first(n))
|
93
|
+
end unless method_defined? :sample
|
94
|
+
|
95
|
+
def shuffle
|
96
|
+
sample(size)
|
97
|
+
end unless method_defined? :shuffle
|
98
|
+
|
99
|
+
def shuffle!
|
100
|
+
replace(sample(size))
|
101
|
+
end unless method_defined? :shuffle!
|
102
|
+
|
83
103
|
end
|
data/lib/backports/enumerable.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Enumerable
|
2
2
|
# Standard in rails... See official documentation[http://api.rubyonrails.org/classes/Enumerable.html]
|
3
|
+
# Modified from rails 2.3 to not rely on size
|
3
4
|
def sum(identity = 0, &block)
|
4
|
-
return identity unless size > 0
|
5
|
-
|
6
5
|
if block_given?
|
7
|
-
map(&block).sum
|
6
|
+
map(&block).sum(identity)
|
8
7
|
else
|
9
|
-
inject { |sum, element| sum + element }
|
8
|
+
inject { |sum, element| sum + element } || identity
|
10
9
|
end
|
11
10
|
end unless method_defined? :sum
|
12
11
|
|
@@ -86,6 +85,7 @@ module Enumerable
|
|
86
85
|
alias_method_chain :each_slice, :optional_block
|
87
86
|
end
|
88
87
|
|
88
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
89
89
|
def count(*arg)
|
90
90
|
result = 0
|
91
91
|
if block_given?
|
@@ -99,11 +99,13 @@ module Enumerable
|
|
99
99
|
result
|
100
100
|
end unless method_defined? :count
|
101
101
|
|
102
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
102
103
|
def cycle(*arg, &block)
|
103
104
|
return to_enum(:cycle, *arg) unless block_given?
|
104
105
|
to_a.cycle(*arg, &block)
|
105
106
|
end unless method_defined? :cycle
|
106
107
|
|
108
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
107
109
|
unless ((1..2).each_cons(1) rescue false)
|
108
110
|
def each_cons_with_optional_block(len, &block)
|
109
111
|
raise ArgumentError, "invalid size" if len <= 0
|
@@ -113,12 +115,19 @@ module Enumerable
|
|
113
115
|
alias_method_chain :each_cons, :optional_block
|
114
116
|
end
|
115
117
|
|
118
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
116
119
|
def group_by
|
117
120
|
return to_enum(:group_by) unless block_given?
|
118
121
|
returning({}) do |result|
|
119
122
|
each do |o|
|
120
|
-
result.fetch(yield
|
123
|
+
result.fetch(yield(o)){|key| result[key] = []} << o
|
121
124
|
end
|
122
125
|
end
|
123
126
|
end unless method_defined? :group_by
|
127
|
+
|
128
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
129
|
+
def none?(&block)
|
130
|
+
!any?(&block)
|
131
|
+
end unless method_defined? :none?
|
132
|
+
|
124
133
|
end
|
data/lib/backports/string.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
class String
|
2
2
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
3
|
-
def start_with?(
|
4
|
-
|
5
|
-
|
3
|
+
def start_with?(*prefixes)
|
4
|
+
prefixes.each do |prefix|
|
5
|
+
prefix = prefix.to_s
|
6
|
+
return true if self[0, prefix.length] == prefix
|
7
|
+
end
|
8
|
+
false
|
6
9
|
end unless method_defined? :start_with?
|
7
10
|
|
8
11
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
9
|
-
def end_with?(
|
10
|
-
|
11
|
-
|
12
|
+
def end_with?(*suffixes)
|
13
|
+
suffixes.each do |suffix|
|
14
|
+
suffix = suffix.to_s
|
15
|
+
return true if self[-suffix.length, suffix.length] == suffix
|
16
|
+
end
|
17
|
+
false
|
12
18
|
end unless method_defined? :end_with?
|
13
19
|
|
14
20
|
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
@@ -16,6 +22,36 @@ class String
|
|
16
22
|
self[i]
|
17
23
|
end unless method_defined? :getbyte
|
18
24
|
|
25
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
26
|
+
unless method_defined? :each_char
|
27
|
+
VERY_BASIC_UTF8 = Regexp.new("[\x00-\x7f]|[\xc2-\xdf].|[\xe0-\xef]..|[\xf0-\xf4]...").freeze
|
28
|
+
def each_char(&block)
|
29
|
+
return to_enum(:each_char) unless block_given?
|
30
|
+
scan(VERY_BASIC_UTF8, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :chars, :each_char unless method_defined? :chars
|
35
|
+
|
36
|
+
|
37
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
38
|
+
unless ("check partition".partition(" ") rescue false)
|
39
|
+
def partition_with_new_meaning(*args, &block)
|
40
|
+
return partition_without_new_meaning(*args, &block) unless args.length == 1
|
41
|
+
pattern = args.first
|
42
|
+
i = index(pattern)
|
43
|
+
return [self, "", ""] unless i
|
44
|
+
unless pattern.instance_of? Regexp
|
45
|
+
last = i+pattern.length
|
46
|
+
[self[0...i], self[i...last], self[last...length]]
|
47
|
+
else
|
48
|
+
match = Regexp.last_match
|
49
|
+
[match.pre_match, match[0], match.post_match]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
alias_method_chain :partition, :new_meaning
|
53
|
+
end
|
54
|
+
|
19
55
|
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
20
56
|
def camelize(first_letter = :upper)
|
21
57
|
if first_letter == :upper
|
data/test/array_test.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ArrayTest < Test::Unit::TestCase
|
4
|
+
context "Array" do
|
5
|
+
context "#reverse_each" do
|
6
|
+
should "return an enumerator when no block is given" do
|
7
|
+
assert_equal [4,3,2], [1,2,3,4].reverse_each.take(3)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#flatten" do
|
12
|
+
should "conform to doc" do
|
13
|
+
s = [ 1, 2, 3 ] #=> [1, 2, 3]
|
14
|
+
t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
|
15
|
+
a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
|
16
|
+
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a.flatten
|
17
|
+
a = [ 1, 2, [3, [4, 5] ] ]
|
18
|
+
assert_equal [1, 2, 3, [4, 5]], a.flatten(1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#index" do
|
23
|
+
should "conform to doc" do
|
24
|
+
a = [ "a", "b", "c" ]
|
25
|
+
assert_equal 1, a.index("b")
|
26
|
+
assert_equal nil, a.index("z")
|
27
|
+
assert_equal 1, a.index{|x|x=="b"}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#sample" do
|
32
|
+
should "conform to doc" do
|
33
|
+
assert_equal nil, [].sample
|
34
|
+
assert_equal [], [].sample(5)
|
35
|
+
assert_equal 42, [42].sample
|
36
|
+
assert_equal [42], [42].sample(5)
|
37
|
+
a = [ :foo, :bar, 42 ]
|
38
|
+
s = a.sample(2)
|
39
|
+
assert_equal 2, s.size
|
40
|
+
assert_equal 1, (a-s).size
|
41
|
+
assert_equal [], a-(0..20).sum{a.sample(2)} # ~ 3e-10
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class EnumerableTest < Test::Unit::TestCase
|
4
4
|
context "Enumerable" do
|
5
5
|
context "#find_index" do
|
6
6
|
should "conform to doc" do
|
@@ -104,56 +104,5 @@ class BackportsTest < Test::Unit::TestCase
|
|
104
104
|
assert_equal nil, x[:xyz]
|
105
105
|
end
|
106
106
|
end
|
107
|
-
end #Enumerable
|
108
|
-
|
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
|
114
|
-
end
|
115
|
-
|
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
|
125
|
-
end
|
126
|
-
|
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
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context "Hash" do
|
138
|
-
should "should be constructible from key value pairs" do
|
139
|
-
assert_equal({1 => 2, 3 => 4}, Hash[[[1,2],[3,4]]])
|
140
|
-
end
|
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
|
156
|
-
end
|
157
107
|
end
|
158
|
-
|
159
|
-
end
|
108
|
+
end
|
data/test/hash_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HashTest < Test::Unit::TestCase
|
4
|
+
context "Hash" do
|
5
|
+
should "should be constructible from key value pairs" do
|
6
|
+
assert_equal({1 => 2, 3 => 4}, Hash[[[1,2],[3,4]]])
|
7
|
+
end
|
8
|
+
|
9
|
+
context "#default_proc=" do
|
10
|
+
should "conform to doc" do
|
11
|
+
h = { :foo => :bar }
|
12
|
+
h.default = "Go fish"
|
13
|
+
h.default_proc=lambda do |hash, key|
|
14
|
+
key + key
|
15
|
+
end
|
16
|
+
assert_equal :bar, h[:foo]
|
17
|
+
assert_equal 4, h[2]
|
18
|
+
assert_equal "catcat", h["cat"]
|
19
|
+
h.default=nil
|
20
|
+
assert_equal nil, h[2]
|
21
|
+
assert_equal nil, h["cat"]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/test/string_test.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class StringTest < Test::Unit::TestCase
|
5
|
+
context "String" do
|
6
|
+
context "#chars" do
|
7
|
+
should "conform to doc" do
|
8
|
+
assert_equal ["d", "o", "g"], "dog".chars.to_a
|
9
|
+
assert_equal ["δ", "o", "g"], "δog".chars.to_a
|
10
|
+
result = []
|
11
|
+
"δog".chars.each {|b| result << b }
|
12
|
+
assert_equal ["δ", "o", "g"], result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#start_with" do
|
17
|
+
should "conform to doc" do
|
18
|
+
assert "Apache".start_with?("Apa")
|
19
|
+
assert "ruby code".start_with?("python", "perl", "ruby")
|
20
|
+
assert !"hello world".start_with?("world")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#end_with" do
|
25
|
+
should "conform to doc" do
|
26
|
+
assert "Apache".end_with?("ache")
|
27
|
+
assert "ruby code".end_with?("python", "perl", "code")
|
28
|
+
assert !"hello world".end_with?("hello")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "#partition" do
|
33
|
+
should "conform to doc" do
|
34
|
+
assert_equal ["THX", "11", "38"], "THX1138".partition("11")
|
35
|
+
assert_equal ["THX", "11", "38"], "THX1138".partition(/\d\d/)
|
36
|
+
assert_equal ["THX1138", "", ""], "THX1138".partition("99")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
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.3.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-17 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -37,7 +37,10 @@ files:
|
|
37
37
|
- lib/backports/object.rb
|
38
38
|
- lib/backports/string.rb
|
39
39
|
- lib/backports/symbol.rb
|
40
|
-
- test/
|
40
|
+
- test/array_test.rb
|
41
|
+
- test/enumerable_test.rb
|
42
|
+
- test/hash_test.rb
|
43
|
+
- test/string_test.rb
|
41
44
|
- test/test_helper.rb
|
42
45
|
has_rdoc: true
|
43
46
|
homepage: http://github.com/marcandre/backports
|
@@ -72,5 +75,8 @@ signing_key:
|
|
72
75
|
specification_version: 2
|
73
76
|
summary: Backports or ruby 1.8.7+ & rails for older ruby.
|
74
77
|
test_files:
|
75
|
-
- test/
|
78
|
+
- test/array_test.rb
|
79
|
+
- test/enumerable_test.rb
|
80
|
+
- test/hash_test.rb
|
81
|
+
- test/string_test.rb
|
76
82
|
- test/test_helper.rb
|