backports 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|