backports 1.9.0 → 1.10.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.
@@ -1,5 +1,13 @@
1
1
  = Packable --- History
2
2
 
3
+ == Version 1.9.1 - September 29th, 2009
4
+
5
+ * Added Enumerable#chunk (Ruby 1.9)
6
+
7
+ * Added Kernel#respond_to_missing? (Ruby 1.9)
8
+
9
+ * Completed Process.exec (Ruby 1.8.7)
10
+
3
11
  == Version 1.9.0 - September 4th, 2009
4
12
 
5
13
  * In Ruby 1.9, most class methods of File accept filenames as String, or convertible via #to_str or #to_path.
@@ -46,14 +46,15 @@ Compatible with Ruby 1.8 & 1.9, jruby and rubinius.
46
46
 
47
47
  == Ruby 1.8.7
48
48
 
49
- Complete Ruby 1.8.7 backporting. Refer to the official list of changes[http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS].
49
+ Complete Ruby 1.8.7 backporting (core language). Refer to the official list of changes[http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS].
50
50
 
51
51
  Only exceptions:
52
52
  * String#gsub
53
53
  * GC.stress=
54
- * Process.exec
55
54
  * Array#choice (use Array#sample instead)
56
- * recursive data handling (Array and Hash)
55
+ * recursive data handling (Array, Hash, ...)
56
+
57
+ Libraries have not been backported. See at the end for list of known library backports
57
58
 
58
59
  == Ruby 1.9
59
60
 
@@ -64,6 +65,7 @@ Additionally, the following Ruby 1.9 have been backported:
64
65
 
65
66
  * Enumerable
66
67
  * +each_with_object+
68
+ * +chunk+
67
69
 
68
70
  * Enumerator
69
71
  * +new+ (with block)
@@ -82,6 +84,7 @@ Additionally, the following Ruby 1.9 have been backported:
82
84
 
83
85
  * Object
84
86
  * +define_singleton_method+
87
+ * +respond_to_missing?+
85
88
 
86
89
  * Proc
87
90
  * +yield+
@@ -122,6 +125,14 @@ Some generic methods from Rails methods have been copied:
122
125
  * +dasherize+, +demodulize+
123
126
  * +constantize+
124
127
 
128
+ == Libraries
129
+
130
+ Libraries have not been backported. I am aware of following the backport gems:
131
+
132
+ * Net::SMTP for Ruby 1.8.6: smtp_tls[http://seattlerb.rubyforge.org/smtp_tls/]
133
+
134
+ * Let me know of others...
135
+
125
136
  = License
126
137
 
127
138
  +backports+ is released under the terms of the MIT License, see the included LICENSE file.
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 9
3
+ :minor: 10
4
4
  :patch: 0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{backports}
8
- s.version = "1.9.0"
8
+ s.version = "1.10.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Marc-Andr\303\251 Lafortune"]
12
- s.date = %q{2009-09-05}
12
+ s.date = %q{2009-09-29}
13
13
  s.description = %q{ Essential backports that enable some of the really nice features of ruby 1.8.7, ruby 1.9 and rails from ruby 1.8.6 and earlier.
14
14
  }
15
15
  s.email = %q{github@marc-andre.ca}
@@ -55,6 +55,7 @@ Gem::Specification.new do |s|
55
55
  "lib/backports/1.8.7/symbol.rb",
56
56
  "lib/backports/1.9.rb",
57
57
  "lib/backports/1.9/array.rb",
58
+ "lib/backports/1.9/dir.rb",
58
59
  "lib/backports/1.9/enumerable.rb",
59
60
  "lib/backports/1.9/enumerator.rb",
60
61
  "lib/backports/1.9/file.rb",
@@ -62,6 +63,7 @@ Gem::Specification.new do |s|
62
63
  "lib/backports/1.9/integer.rb",
63
64
  "lib/backports/1.9/io.rb",
64
65
  "lib/backports/1.9/kernel.rb",
66
+ "lib/backports/1.9/method.rb",
65
67
  "lib/backports/1.9/string.rb",
66
68
  "lib/backports/1.9/symbol.rb",
67
69
  "lib/backports/basic_object.rb",
@@ -80,6 +82,7 @@ Gem::Specification.new do |s|
80
82
  "test/enumerator_test.rb",
81
83
  "test/hash_test.rb",
82
84
  "test/kernel_test.rb",
85
+ "test/method_missing_test.rb",
83
86
  "test/method_test.rb",
84
87
  "test/module_test.rb",
85
88
  "test/object_test.rb",
@@ -102,6 +105,7 @@ Gem::Specification.new do |s|
102
105
  "test/enumerator_test.rb",
103
106
  "test/hash_test.rb",
104
107
  "test/kernel_test.rb",
108
+ "test/method_missing_test.rb",
105
109
  "test/method_test.rb",
106
110
  "test/module_test.rb",
107
111
  "test/object_test.rb",
@@ -7,8 +7,8 @@ class Array
7
7
  # Implementation note: slightly tricky.
8
8
  # Example: self = 1..7, num = 3
9
9
  picks = (0...num).to_a # picks start at 0, 1, 2
10
- max = ((size-num)...size).to_a # max (index for a given pick) is [4, 5, 6]
11
- pick_max_pairs = picks.zip(max).reverse # pick_max_pairs = [[2, 6], [1, 5], [0, 4]]
10
+ max_index = ((size-num)...size).to_a # max (index for a given pick) is [4, 5, 6]
11
+ pick_max_pairs = picks.zip(max_index).reverse # pick_max_pairs = [[2, 6], [1, 5], [0, 4]]
12
12
  lookup = pick_max_pairs.find(Proc.new{return self})
13
13
  loop do
14
14
  yield values_at(*picks)
@@ -1,9 +1,11 @@
1
1
  module GC
2
- def self.stress
3
- false
4
- end
2
+ class << self
3
+ def stress
4
+ false
5
+ end unless method_defined? :stress
5
6
 
6
- def self.stress=(flag)
7
- raise NotImplementedError
7
+ def stress=(flag)
8
+ raise NotImplementedError
9
+ end unless method_defined? :stress=
8
10
  end
9
11
  end
@@ -42,7 +42,7 @@ class IO
42
42
  end
43
43
 
44
44
  self
45
- end
45
+ end unless method_defined? :each_char
46
46
 
47
47
  alias_method :getbyte, :getc unless method_defined? :getbyte
48
48
  alias_method :readbyte, :readchar unless method_defined? :readchar
@@ -24,7 +24,7 @@ unless Method.method_defined? :name
24
24
  Backports.alias_method_chain self, :bind, :additional_info
25
25
  end
26
26
 
27
- class Object
27
+ module Kernel
28
28
  def method_with_additional_info(name)
29
29
  method_without_additional_info(name).tap do |bound|
30
30
  bound.name = name.to_sym
@@ -1,5 +1,3 @@
1
1
  module Process
2
- def self.exec(*args)
3
- raise NotImplementedError
4
- end
2
+ module_function :exec unless class << self; method_defined? :exec; end
5
3
  end
@@ -1,5 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/tools")
2
2
  Backports.require_relative "1.8.7"
3
- %w(array enumerable enumerator hash file integer io kernel string symbol).each do |lib|
3
+ %w(array dir enumerable enumerator hash file integer io kernel method string symbol).each do |lib|
4
4
  Backports.require_relative "1.9/#{lib}"
5
5
  end
@@ -7,6 +7,6 @@ class Array
7
7
  def try_convert(obj)
8
8
  return nil unless obj.respond_to?(:to_ary)
9
9
  Backports.coerce_to(obj, Array, :to_ary)
10
- end
10
+ end unless method_defined? :try_convert
11
11
  end
12
12
  end
@@ -0,0 +1,3 @@
1
+ class Dir
2
+ alias_method :to_path, :path unless method_defined? :to_path
3
+ end
@@ -5,4 +5,32 @@ module Enumerable
5
5
  each {|obj| block.call(obj, memo)}
6
6
  memo
7
7
  end unless method_defined? :each_with_object
8
+
9
+ def chunk(initial_state = nil, &original_block)
10
+ Enumerator.new do |yielder|
11
+ previous = Backports::Undefined
12
+ accumulate = []
13
+ block = initial_state.nil? ? original_block : Proc.new{|val| original_block.yield(val, initial_state.clone)}
14
+ each do |val|
15
+ case key = block.yield(val)
16
+ when nil, :_separator
17
+ next
18
+ when :_singleton
19
+ yielder.yield previous, accumulate unless accumulate.empty?
20
+ yielder.yield key, [val]
21
+ accumulate = []
22
+ previous = Backports::Undefined
23
+ when previous, Backports::Undefined
24
+ accumulate << val
25
+ previous = key
26
+ else
27
+ yielder.yield previous, accumulate unless accumulate.empty?
28
+ accumulate = [val]
29
+ previous = key
30
+ end
31
+ end
32
+ # what to do in case of a break?
33
+ yielder.yield previous, accumulate unless accumulate.empty?
34
+ end
35
+ end
8
36
  end
@@ -5,7 +5,7 @@ class Hash
5
5
  def try_convert(x)
6
6
  return nil unless x.respond_to? :to_hash
7
7
  x.to_hash
8
- end unless method_defined? :to_hash
8
+ end unless method_defined? :try_convert
9
9
  end
10
10
 
11
11
  # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
@@ -0,0 +1,101 @@
1
+ # Standard in Ruby 1.9.2. How do you call the backport of a future feature?
2
+ unless Kernel.method_defined? :respond_to_missing?
3
+ module MissingMethod
4
+ attr_reader :name
5
+
6
+ def call(*arg, &block)
7
+ receiver.send :method_missing, @name, *arg, &block
8
+ end
9
+ alias_method :[], :call
10
+
11
+ def eql?(method)
12
+ method.is_a?(MissingMethod) &&
13
+ receiver == method.receiver &&
14
+ name == method.name
15
+ end
16
+ alias_method :==, :eql?
17
+
18
+ def arity
19
+ -1
20
+ end
21
+
22
+ def owner
23
+ @receiver.class
24
+ end
25
+
26
+ def source_location
27
+ nil
28
+ end
29
+
30
+ def to_proc
31
+ get_block {|*arg| @receiver.send :method_missing, *arg}
32
+ end
33
+
34
+ def unbind
35
+ MissingUnboundMethod.new(owner, name)
36
+ end
37
+
38
+ def self.new(receiver, name)
39
+ m = receiver.method :respond_to_missing?
40
+ m.extend self
41
+ m.instance_variable_set :@name, name
42
+ m
43
+ end
44
+ #private
45
+ def get_block(&block)
46
+ block
47
+ end
48
+ private :get_block
49
+ end
50
+
51
+ module MissingUnboundMethod
52
+ attr_reader :name
53
+ attr_reader :owner
54
+
55
+ def self.new(owner, name)
56
+ um = owner.instance_method :respond_to_missing?
57
+ um.extend self
58
+ um.instance_variable_set :@name, name
59
+ um.instance_variable_set :@owner, owner
60
+ um
61
+ end
62
+
63
+ def arity
64
+ -1
65
+ end
66
+
67
+ def source_location
68
+ nil
69
+ end
70
+
71
+ def bind(to)
72
+ raise TypeError, "bind argument must be an instance of #{@owner}" unless to.is_a? @owner
73
+ MissingMethod.new(to, @name)
74
+ end
75
+ end
76
+
77
+ module Kernel
78
+ def respond_to_missing? method
79
+ false
80
+ end
81
+
82
+ def respond_to_with_call_to_respond_to_missing? method
83
+ respond_to_without_call_to_respond_to_missing?(method) || respond_to_missing?(method)
84
+ end
85
+ Backports.alias_method_chain self, :respond_to?, :call_to_respond_to_missing
86
+
87
+ def method_with_new_repond_to_missing(method)
88
+ method_without_new_repond_to_missing(method)
89
+ rescue NameError
90
+ respond_to_missing?(method) ? MissingMethod.new(self, method): raise
91
+ end
92
+ Backports.alias_method_chain self, :method, :new_repond_to_missing
93
+
94
+ def public_method_with_new_repond_to_missing(method)
95
+ public_method_without_new_repond_to_missing(method)
96
+ rescue NameError
97
+ respond_to_missing?(method) ? MissingMethod.new(self, method): raise
98
+ end
99
+ Backports.alias_method_chain self, :public_method, :new_repond_to_missing if method_defined? :public_method
100
+ end
101
+ end
@@ -7,7 +7,7 @@ class EnumerableTest < Test::Unit::TestCase
7
7
  should "conform to doc" do
8
8
  assert_equal 4, (1..4).count
9
9
  assert_equal 1, (1..4).count(3)
10
- assert_equal 2, (1..4).count{|obj| obj > 2 }
10
+ assert_equal 2, (1..4).count{|obj| obj > 2 }
11
11
  end
12
12
  end
13
13
 
@@ -16,21 +16,21 @@ class EnumerableTest < Test::Unit::TestCase
16
16
  assert_equal ["a", "b", "c", "a", "b", "c"], ('a'..'c').cycle(2).to_a
17
17
  end
18
18
  end
19
-
19
+
20
20
  context "#drop" do
21
21
  should "conform to doc" do
22
22
  assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
23
23
  assert_equal [], [ 1, 1, 2, 3, 5, 8, 13 ].drop(99)
24
24
  end
25
-
25
+
26
26
  should "work with enums" do
27
27
  assert_equal [14,15], (10...16).drop(4)
28
28
  end
29
29
  end
30
-
30
+
31
31
  context "#drop_while" do
32
32
  should "conform to doc" do
33
- assert_equal [8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop_while {|item| item < 6 }
33
+ assert_equal [8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop_while {|item| item < 6 }
34
34
  end
35
35
 
36
36
  should "work with enums" do
@@ -42,13 +42,13 @@ class EnumerableTest < Test::Unit::TestCase
42
42
  assert_equal [], (10...16).drop_while {|item| true}
43
43
  end
44
44
  end
45
-
45
+
46
46
  context "#each_cons" do
47
47
  should "conform to doc" do
48
48
  assert_equal [[1,2],[2,3],[3,4]], (1..4).each_cons(2).to_a
49
49
  end
50
50
  end
51
-
51
+
52
52
  context "#each_slice" do
53
53
  should "conform to doc" do
54
54
  res = []
@@ -60,10 +60,10 @@ class EnumerableTest < Test::Unit::TestCase
60
60
 
61
61
  context "#each_with_index" do
62
62
  should "conform to doc" do
63
- hash = Hash.new
64
- %w(cat dog wombat).each_with_index do |item, index|
65
- hash[item] = index
66
- end
63
+ hash = Hash.new
64
+ %w(cat dog wombat).each_with_index do |item, index|
65
+ hash[item] = index
66
+ end
67
67
  assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
68
68
  end
69
69
 
@@ -76,9 +76,9 @@ class EnumerableTest < Test::Unit::TestCase
76
76
 
77
77
  context "#each_with_object" do
78
78
  should "conform to doc" do
79
- hash = %w(cat dog wombat).each_with_object({}) do |item, memo|
80
- memo[item] = item.upcase.reverse
81
- end
79
+ hash = %w(cat dog wombat).each_with_object({}) do |item, memo|
80
+ memo[item] = item.upcase.reverse
81
+ end
82
82
  assert_equal({"cat"=>"TAC", "dog"=>"GOD", "wombat"=>"TABMOW"}, hash)
83
83
  end
84
84
  end
@@ -123,28 +123,28 @@ class EnumerableTest < Test::Unit::TestCase
123
123
 
124
124
  context "#max_by" do
125
125
  should "conform to doc" do
126
- a = %w(albatross dog horse fox)
126
+ a = %w(albatross dog horse fox)
127
127
  assert_equal "albatross" , a.max_by {|item| item.length }
128
128
  assert_equal "fox", a.max_by {|item| item.reverse }
129
129
  end
130
- end
130
+ end
131
131
 
132
132
  context "#min_by" do
133
133
  should "conform to doc" do
134
- a = %w(albatross dog horse fox)
134
+ a = %w(albatross dog horse fox)
135
135
  assert_equal "dog" , a.min_by {|item| item.length }
136
136
  assert_equal "horse", a.min_by {|item| item.reverse }
137
137
  end
138
- end
138
+ end
139
139
 
140
140
  context "#minmax" do
141
141
  should "conform to doc" do
142
- a = %w(albatross dog horse)
142
+ a = %w(albatross dog horse)
143
143
  assert_equal ["albatross", "horse"], a.minmax
144
144
  assert_equal ["dog", "albatross"], a.minmax {|a,b| a.length <=> b.length }
145
145
  end
146
146
  end
147
-
147
+
148
148
  context "#one" do
149
149
  should "conform to doc" do
150
150
  assert_equal false, %w{ ant bear cat}.one? {|word| word.length >= 3}
@@ -152,25 +152,25 @@ class EnumerableTest < Test::Unit::TestCase
152
152
  assert_equal true, [ nil, nil, 99 ].one?
153
153
  end
154
154
  end
155
-
155
+
156
156
  context "#reverse_each" do
157
157
  should "work as expected" do
158
158
  assert_equal [4,3,2], (1..4).reverse_each.take(3)
159
159
  end
160
160
  end
161
-
161
+
162
162
  context "#take" do
163
163
  should "conform to doc" do
164
164
  assert_equal [1, 2, 3], (1..7).take(3)
165
165
  assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
166
166
  end
167
-
167
+
168
168
  should "only consume what's needed" do
169
169
  assert_equal [], Enumerator.new(nil).take(0)
170
170
  assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
171
171
  end
172
172
  end
173
-
173
+
174
174
  context "#take_while" do
175
175
  should "conform to doc" do
176
176
  assert_equal [1,2], (1..7).take_while {|item| item < 3 }
@@ -189,5 +189,33 @@ class EnumerableTest < Test::Unit::TestCase
189
189
  end
190
190
  end
191
191
 
192
+ context "#chunk" do
193
+ context "given no argument" do
194
+ should "should chunk correctly even for non-consecutive but similar keys" do
195
+ e = (1..7).chunk{|i| (i/3) % 2}
196
+ assert_equal true, e.is_a?(Enumerator)
197
+ assert_equal [
198
+ [0, [1,2]],
199
+ [1, [3,4,5]],
200
+ [0, [6,7]]], e.to_a
201
+ end
202
+ end
203
+ context "given an initial_state argument" do
204
+ should "give a new copy" do
205
+ a = []
206
+ e = (1..3).chunk(a) do |i, x|
207
+ assert_equal true, x.empty?
208
+ x << :yo
209
+ :_singleton
210
+ end
211
+ assert_equal [
212
+ [:_singleton, [1]],
213
+ [:_singleton, [2]],
214
+ [:_singleton, [3]]], e.to_a
215
+ end
216
+ end
217
+
218
+ end
219
+
192
220
  end
193
221
  end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+
4
+ class MethodMissingTest < Test::Unit::TestCase
5
+
6
+ class A
7
+ def respond_to_missing? method
8
+ :ok_if_missing == method
9
+ end
10
+
11
+ def method_missing method, *args
12
+ :bar
13
+ end
14
+ end
15
+
16
+ context "#respond_to?" do
17
+ should "takes #respond_to_missing? into account" do
18
+ assert_equal true, A.new.respond_to?(:ok_if_missing)
19
+ assert_equal false, A.new.respond_to?(:not_ok_if_missing)
20
+ end
21
+ end
22
+
23
+ context "#method" do
24
+ should "returns a nice Method with respond_to_missing?" do
25
+ assert_equal :bar, A.new.method(:ok_if_missing).call
26
+ assert_raise(NameError){ A.new.method(:not_ok_if_missing) }
27
+ end
28
+ end
29
+
30
+ context "Method#unbind" do
31
+ should "works for missing Methods" do
32
+ assert_equal :ok_if_missing, A.new.method(:ok_if_missing).unbind.name
33
+ end
34
+ end
35
+
36
+
37
+ 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.9.0
4
+ version: 1.10.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-09-05 00:00:00 -04:00
12
+ date: 2009-09-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -60,6 +60,7 @@ files:
60
60
  - lib/backports/1.8.7/symbol.rb
61
61
  - lib/backports/1.9.rb
62
62
  - lib/backports/1.9/array.rb
63
+ - lib/backports/1.9/dir.rb
63
64
  - lib/backports/1.9/enumerable.rb
64
65
  - lib/backports/1.9/enumerator.rb
65
66
  - lib/backports/1.9/file.rb
@@ -67,6 +68,7 @@ files:
67
68
  - lib/backports/1.9/integer.rb
68
69
  - lib/backports/1.9/io.rb
69
70
  - lib/backports/1.9/kernel.rb
71
+ - lib/backports/1.9/method.rb
70
72
  - lib/backports/1.9/string.rb
71
73
  - lib/backports/1.9/symbol.rb
72
74
  - lib/backports/basic_object.rb
@@ -85,6 +87,7 @@ files:
85
87
  - test/enumerator_test.rb
86
88
  - test/hash_test.rb
87
89
  - test/kernel_test.rb
90
+ - test/method_missing_test.rb
88
91
  - test/method_test.rb
89
92
  - test/module_test.rb
90
93
  - test/object_test.rb
@@ -134,6 +137,7 @@ test_files:
134
137
  - test/enumerator_test.rb
135
138
  - test/hash_test.rb
136
139
  - test/kernel_test.rb
140
+ - test/method_missing_test.rb
137
141
  - test/method_test.rb
138
142
  - test/module_test.rb
139
143
  - test/object_test.rb