marcandre-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 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 ruby 1.8.7, ruby 1.9 and rails from ruby 1.8.x
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 rails or ruby
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 activesupport (even things like <tt>String::pluralize</tt>), won't be included. <tt>require 'activesupport'</tt> if you need them!
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 those as I need them; pull requests welcome (with tests for ruby 1.9 backports)
15
+ I've added these backports as I need them; pull requests welcome (with tests for Ruby 1.9 backports)
16
16
 
17
- == Compatibility
17
+ == Installation & compatibility
18
18
 
19
- Works with ruby 1.8 & 1.9
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 ruby, and +Enumerator+ can be accessed directly (instead of <tt>Enumerable::Enumerator</tt>)
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
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 2
3
+ :minor: 3
4
4
  :patch: 0
@@ -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
@@ -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 o){|key| result[key] = []} << o
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
@@ -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?(prefix)
4
- prefix = prefix.to_s
5
- self[0, prefix.length] == prefix
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?(suffix)
10
- suffix = suffix.to_s
11
- self[-suffix.length, suffix.length] == suffix
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
@@ -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 BackportsTest < Test::Unit::TestCase
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
@@ -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: marcandre-backports
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
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 00:00:00 -07:00
12
+ date: 2009-04-17 00:00:00 -07: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/backports_test.rb
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/backports_test.rb
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