backports 1.5.0 → 1.6.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,11 +1,88 @@
1
1
  = Packable --- History
2
2
 
3
+ == Version 1.6 - April 29, 2009
4
+
5
+ Completed backport to 1.8.7.
6
+
7
+ * Array
8
+ * <tt>extract_options!</tt>
9
+
10
+ * Binding
11
+ * +eval+
12
+
13
+ * Dir
14
+ * +each+, +foreach+
15
+
16
+ * Enumerator
17
+ * +new+
18
+ * +with_object+
19
+ * +next+, +rewind+
20
+
21
+ * Hash
22
+ * Optional block for <tt>delete_if, each, each_key, each_pair, each_value, reject!, select</tt> (and ENV)
23
+
24
+ * Integer
25
+ * moved stuff out of Fixnum
26
+ * Optional block for +downto+, +times+, +upto+
27
+
28
+ * IO
29
+ * Optional block for +each+, +each_line+, +each_byte+, +foreach+ (and ARGF)
30
+
31
+ * Kernel
32
+ * +loop+, +StopIteration+
33
+ * +__method__+, +__callee__+
34
+
35
+ * Method
36
+ * +name+, +owner+, +receiver+
37
+
38
+ * Module
39
+ * +class_exec+, +module_exec+
40
+
41
+ * Numeric
42
+ * +step+
43
+
44
+ * Object
45
+ * +define_singleton_method+
46
+ * +instance_exec+
47
+
48
+ * ObjectSpace
49
+ * +each_object+
50
+
51
+ * Range
52
+ * Optional block for +each+, +step+
53
+
54
+ * Regexp
55
+ * +union+
56
+
57
+ * String
58
+ * +try_convert+
59
+ * <tt>ascii_only?</tt>
60
+ * +bytesize+
61
+ * +chr+
62
+ * +clear+
63
+ * +codepoints+, +each_codepoint+
64
+ * +stringify_keys+, +stringify_keys!+
65
+ * +each+, +each_line+, +each_byte+
66
+ * +gsub+
67
+ * +upto+
68
+
69
+ * Struct
70
+ * +each+, +each_pair+
71
+
72
+ * Symbol
73
+ * <tt><=></tt>, +casecmp+
74
+ * +capitalize+, +downcase+, +next+, +succ+, +swapcase+, +upcase+
75
+ * <tt>=~, [], empty?, length, match, size</tt>
76
+
77
+ * UnboundMethod
78
+ * +name+, +owner+
79
+
3
80
  == Version 1.5 - April 24, 2009
4
81
 
5
82
  * Array (completed)
6
83
  * +combination+
7
84
  * +try_convert+
8
- * Optional block for collect!, :map!, :each, :each_index, :reject, :reject!, :delete_if
85
+ * Optional block for <tt>collect!, :map!, :each, :each_index, :reject, :reject!, :delete_if</tt>
9
86
  * +pop+, +shift+
10
87
  * +product+
11
88
 
@@ -30,45 +30,95 @@ Compatible with Ruby 1.8 & 1.9.
30
30
 
31
31
  = List of backports
32
32
 
33
+ == Ruby 1.8.7
34
+
35
+ 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]. All builtin classes are compatible with Ruby 1.8.7:
36
+ * Array
37
+ * Binding
38
+ * Dir
39
+ * Enumerable
40
+ * Enumerator
41
+ * Fixnum
42
+ * Hash
43
+ * Integer
44
+ * IO (& ARGF)
45
+ * Method
46
+ * Numeric
47
+ * Object
48
+ * ObjectSpace
49
+ * Range
50
+ * Regexp
33
51
  * Symbol
34
- * +to_proc+ (e.g. <tt>foo.map(&:bar)</tt> )
52
+ * UnboundMethod
53
+
54
+ Only exceptions:
55
+ * GC.stress=
56
+ * Process.exec
57
+ * recursive data handling (Array and Hash)
58
+
59
+ As in Ruby 1.8.7+, there is no need to <tt>require 'enumerator'</tt> in older Ruby, and +Enumerator+ can be accessed directly (instead of <tt>Enumerable::Enumerator</tt>)
60
+
61
+ == Ruby 1.9
62
+
63
+ Additionally, the following Ruby 1.9 have been backported:
64
+
65
+ * Array
66
+ * +sample+
67
+
68
+ * Enumerable
69
+ * +each_with_object+
70
+ * +reverse_each+
71
+
72
+ * Enumerator
73
+ * +new+ (with block)
74
+
75
+ * Hash
76
+ * <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
77
+ * <tt>default_proc=</tt>
78
+
35
79
  * Kernel
36
80
  * +require_relative+
81
+
82
+ * Object
83
+ * +define_singleton_method+
84
+
85
+ * Proc
86
+ * +yield+
87
+
88
+ * String
89
+ * +try_convert+
90
+ * <tt>ascii_only?</tt>
91
+ * +chr+
92
+ * +clear+
93
+ * +codepoints+, +each_codepoint+
94
+
95
+ _note_: This usage of <tt>Hash::[]</tt> is not yet documented[http://redmine.ruby-lang.org/issues/show/1385].
96
+
97
+ == Rails
98
+
99
+ Some generic methods from Rails methods have been copied:
100
+
101
+ * Enumerable
102
+ * +sum+
103
+
104
+ * Hash
105
+ * +symbolize_keys+, <tt>symbolize_keys!</tt>
106
+ * +reverse_merge+, <tt>reverse_merge!</tt>
107
+
37
108
  * Module
38
109
  * +alias_method_chain+
110
+
39
111
  * Object
40
- * +tap+, +returning+
41
112
  * +try+
113
+ * +returning+
114
+
42
115
  * String
43
- * +each_char+, +chars+
44
- * <tt>start_with?</tt>, <tt>end_with?</tt>
45
116
  * +camelize+, +underscore+
46
117
  * +dasherize+, +demodulize+
47
118
  * +constantize+
48
- * +partition+, +rpartition+
49
- * Hash
50
- * +symbolize_keys+, <tt>symbolize_keys!</tt>
51
- * +reverse_merge+, <tt>reverse_merge!</tt>
52
- * <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
53
- * +key+
54
- * <tt>default_proc=</tt>
55
- * Enumerable
56
- * +sum+
57
- * complete Ruby 1.8.7 backport
58
- * Array
59
- * complete Ruby 1.8.7 backport
60
- * Fixnum
61
- * complete Ruby 1.8.7 backport
62
- * Proc
63
- * +yield+
64
-
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>)
66
-
67
- _note_: This usage of <tt>Hash::[]</tt> is not yet documented[http://redmine.ruby-lang.org/issues/show/1385].
68
119
 
69
120
  = License
70
121
 
71
122
  +backports+ is released under the terms of the MIT License, see the included LICENSE file.
72
- The code for backports was copied from rails when available.
73
123
 
74
124
  Author:: Marc-André Lafortune
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 5
3
+ :minor: 6
4
4
  :patch: 0
@@ -10,6 +10,13 @@ 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 proc).each do |lib|
13
+ class Array
14
+ # Standard in rails, and we use it in module.
15
+ def extract_options!
16
+ last.is_a?(::Hash) ? pop : {}
17
+ end unless method_defined? :extract_options!
18
+ end
19
+
20
+ %w(object module kernel object_space array enumerable enumerator string symbol integer fixnum hash proc binding dir io method regexp struct).each do |lib|
14
21
  require_relative "backports/#{lib}"
15
22
  end
@@ -7,19 +7,7 @@ class Array
7
7
  end
8
8
 
9
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
10
+ make_block_optional :collect!, :map!, :each, :each_index, :reverse_each, :reject, :reject!, :delete_if, :test_on => [42]
23
11
 
24
12
  # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
25
13
  def combination(num)
@@ -47,6 +35,8 @@ class Array
47
35
  nb.to_i.times{each(&block)}
48
36
  end unless method_defined? :cycle
49
37
 
38
+ # extract_options! in backports.rb
39
+
50
40
  # flatten & flatten!, standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
51
41
  unless ([[]].flatten(1) rescue false)
52
42
 
@@ -72,8 +62,7 @@ class Array
72
62
  alias_method_chain :flatten, :optional_argument
73
63
  alias_method_chain :flatten!, :optional_argument
74
64
 
75
- # Helper to recurse through flattening since the method
76
- # is not allowed to recurse itself. Detects recursive structures.
65
+ # Helper to recurse through flattening
77
66
  # Adapted from rubinius'; recursion guards are not needed because level is finite
78
67
  def recursively_flatten_finite(array, out, level)
79
68
  ret = nil
@@ -116,19 +105,19 @@ class Array
116
105
  end
117
106
 
118
107
  def product(*arg)
119
- arg.unshift(self)
120
- arg._partial_cartesian_product(arg.size-1, Array.new(arg.size), [])
108
+ arrays = [self, *arg].reverse
109
+ first_enum = Enumerator.new{|yielder| yielder.yield [] }
110
+ arrays.inject(first_enum) do |enum, array|
111
+ Enumerator.new do |yielder|
112
+ array.each do |obj|
113
+ enum.each do |partial_product|
114
+ yielder.yield [obj] + partial_product
115
+ end
116
+ end
117
+ end
118
+ end.to_a
121
119
  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
-
120
+
132
121
  # rindex
133
122
  unless ([1].rindex{true} rescue false)
134
123
  def rindex_with_block(*arg)
@@ -0,0 +1,6 @@
1
+ class Binding
2
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Symbol.html]
3
+ def eval(expr, *arg)
4
+ Kernel.eval(expr, self, *arg)
5
+ end unless method_defined? :eval
6
+ end
@@ -0,0 +1,7 @@
1
+ class Dir
2
+ make_block_optional :each, :test_on => Dir.new(".")
3
+ class << self
4
+ make_block_optional :foreach, :test_on => Dir, :arg => "."
5
+ end
6
+ end
7
+
@@ -29,15 +29,7 @@ module Enumerable
29
29
  to_a.cycle(*arg, &block)
30
30
  end unless method_defined? :cycle
31
31
 
32
- # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
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)
37
- end
38
- alias_method_chain :detect, :optional_block
39
- alias_method :find, :detect
40
- end
32
+ make_block_optional :detect, :find, :test_on => [42]
41
33
 
42
34
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
43
35
  def drop(n)
@@ -56,24 +48,7 @@ module Enumerable
56
48
  end unless method_defined? :drop_while
57
49
 
58
50
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
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
67
-
68
- # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
69
- unless ((1..2).each_slice(1) rescue false)
70
- def each_slice_with_optional_block(len, &block)
71
- raise ArgumentError, "invalid slice size" if len <= 0
72
- return to_enum(:each_slice, len) unless block_given?
73
- each_slice_without_optional_block(len, &block)
74
- end
75
- alias_method_chain :each_slice, :optional_block
76
- end
51
+ make_block_optional :each_cons, :each_slice, :test_on => 1..2, :arg => 1
77
52
 
78
53
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
79
54
  if instance_method(:each_with_index).arity.zero?
@@ -93,6 +68,7 @@ module Enumerable
93
68
 
94
69
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
95
70
  def find_index(*args)
71
+ raise ArgumentError, "Wrong number of arguments (#{args.size} for 1)" if args.size > 1
96
72
  if args.size == 1
97
73
  obj = args.first
98
74
  each_with_index do |element, i|
@@ -104,7 +80,7 @@ module Enumerable
104
80
  end
105
81
  each_with_index{|o,i| return i if yield o}
106
82
  else
107
- raise ArgumentError, "Wrong number of arguments (#{args.size} for 1)"
83
+ return to_enum(:find_index)
108
84
  end
109
85
  nil
110
86
  end unless method_defined? :find_index
@@ -239,7 +215,3 @@ module Enumerable
239
215
  end
240
216
 
241
217
  end
242
-
243
- class Enumerator
244
- alias_method :with_object, :each_with_object unless method_defined? :with_object
245
- end
@@ -0,0 +1,41 @@
1
+ class Enumerator
2
+ alias_method :with_object, :each_with_object unless method_defined? :with_object
3
+
4
+ def next
5
+ require 'generator'
6
+ @generator ||= Generator.new(self)
7
+ raise StopIteration unless @generator.next?
8
+ @generator.next
9
+ end unless method_defined? :next
10
+
11
+ def rewind
12
+ require 'generator'
13
+ @generator ||= Generator.new(self)
14
+ @generator.rewind
15
+ self
16
+ end unless method_defined? :rewind
17
+
18
+ # new with block, standard in Ruby 1.9
19
+ unless (self.new{} rescue false)
20
+ class Yielder
21
+ def initialize(&block)
22
+ @main_block = block
23
+ end
24
+
25
+ def each(&block)
26
+ @final_block = block
27
+ @main_block.call(self)
28
+ end
29
+
30
+ def yield(*arg)
31
+ @final_block.yield(*arg)
32
+ end
33
+ end
34
+
35
+ def initialize_with_optional_block(*arg, &block)
36
+ return initialize_without_optional_block(*arg, &nil) unless arg.empty? # Ruby 1.9 apparently ignores the block if any argument is present
37
+ initialize_without_optional_block(Yielder.new(&block))
38
+ end
39
+ alias_method_chain :initialize, :optional_block
40
+ end
41
+ end
@@ -4,30 +4,8 @@ class Fixnum
4
4
  (self / n).round
5
5
  end unless method_defined? :div
6
6
 
7
- # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
8
- def even?
9
- self & 1 == 0
10
- end unless method_defined? :even?
11
-
12
7
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
13
8
  def fdiv(n)
14
9
  to_f / n
15
10
  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
-
33
11
  end
@@ -16,16 +16,13 @@ class Hash
16
16
  end unless method_defined? :to_hash
17
17
  end
18
18
 
19
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
20
- def symbolize_keys
21
- Hash[map{|key,value| [(key.to_sym rescue key) || key, value] }]
22
- end unless method_defined? :symbolize_keys
23
-
24
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
25
- def symbolize_keys!
26
- self.replace(self.symbolize_keys)
27
- end unless method_defined? :symbolize_keys!
19
+ make_block_optional :delete_if, :each, :each_key, :each_pair, :each_value, :reject!, :select, :test_on => {:hello => "world!"}
28
20
 
21
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
22
+ def default_proc=(proc)
23
+ replace(Hash.new(&proc).merge!(self))
24
+ end unless method_defined? :default_proc=
25
+
29
26
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
30
27
  alias_method :key, :index unless method_defined? :key
31
28
 
@@ -39,8 +36,27 @@ class Hash
39
36
  replace(reverse_merge(other_hash))
40
37
  end
41
38
 
42
- # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
43
- def default_proc=(proc)
44
- replace(Hash.new(&proc).merge!(self))
45
- end unless method_defined? :default_proc=
39
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
40
+ def symbolize_keys
41
+ Hash[map{|key,value| [(key.to_sym rescue key) || key, value] }]
42
+ end unless method_defined? :symbolize_keys
43
+
44
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
45
+ def symbolize_keys!
46
+ self.replace(self.symbolize_keys)
47
+ end unless method_defined? :symbolize_keys!
48
+
49
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
50
+ def stringify_keys
51
+ Hash[map{|key,value| [key.to_s, value] }]
52
+ end unless method_defined? :stringify_keys
53
+
54
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
55
+ def stringify_keys!
56
+ self.replace(self.stringify_keys)
57
+ end unless method_defined? :stringify_keys!
58
+ end
59
+
60
+ class << ENV
61
+ make_block_optional :delete_if, :each, :each_key, :each_pair, :each_value, :reject!, :select, :test_on => ENV
46
62
  end
@@ -0,0 +1,34 @@
1
+ class Integer
2
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
3
+ def even?
4
+ self[0].zero?
5
+ end unless method_defined? :even?
6
+
7
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
8
+ def odd?
9
+ !even?
10
+ end unless method_defined? :odd?
11
+
12
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
13
+ def ord
14
+ self
15
+ end
16
+
17
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
18
+ def succ
19
+ self + 1
20
+ end unless method_defined? :succ
21
+
22
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
23
+ def pred
24
+ self - 1
25
+ end unless method_defined? :succ
26
+
27
+ alias_method :magnitude, :abs unless method_defined? :magnitude
28
+
29
+ make_block_optional :downto, :times, :upto, :test_on => 42, :arg => 42
30
+ end
31
+
32
+ class Numeric
33
+ make_block_optional :step, :test_on => 42, :arg => [100, 6]
34
+ end
@@ -0,0 +1,12 @@
1
+ if RUBY_VERSION < '1.8.7'
2
+ class IO
3
+ make_block_optional :each, :each_line, :each_byte
4
+ class << self
5
+ make_block_optional :foreach
6
+ end
7
+ end
8
+
9
+ class << ARGF
10
+ make_block_optional :each, :each_line, :each_byte
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module Kernel
2
+ unless const_defined? :StopIteration
3
+
4
+ class StopIteration < IndexError; end
5
+
6
+ def loop_with_stop_iteration(&block)
7
+ loop_without_stop_iteration(&block)
8
+ rescue StopIteration
9
+ # ignore silently
10
+ end
11
+ alias_method_chain :loop, :stop_iteration
12
+
13
+ end
14
+
15
+ def __callee__
16
+ caller(1).first[/`(.*)'/,1].try(:to_sym)
17
+ end unless (__callee__ || true rescue false)
18
+
19
+ alias_method :__method__, :__callee__ unless (__method__ || true rescue false)
20
+ end
@@ -0,0 +1,47 @@
1
+ unless Method.method_defined? :name
2
+ class Method
3
+ attr_accessor :name, :receiver, :owner
4
+
5
+ def unbind_with_additional_info
6
+ returning unbind_without_additional_info do |unbound|
7
+ unbound.name = name
8
+ unbound.owner = owner
9
+ end
10
+ end
11
+ alias_method_chain :unbind, :additional_info
12
+ end
13
+
14
+ class UnboundMethod
15
+ attr_accessor :name, :owner
16
+
17
+ def bind_with_additional_info(to)
18
+ returning bind_without_additional_info(to) do |bound|
19
+ bound.name = name
20
+ bound.owner = owner
21
+ bound.receiver = to
22
+ end
23
+ end
24
+ alias_method_chain :bind, :additional_info
25
+ end
26
+
27
+ class Object
28
+ def method_with_additional_info(name)
29
+ returning method_without_additional_info(name) do |bound|
30
+ bound.name = name.to_sym
31
+ bound.receiver = self
32
+ bound.owner = self.class.ancestors.find{|mod| mod.instance_methods(false).include? name.to_s}
33
+ end
34
+ end
35
+ alias_method_chain :method, :additional_info
36
+ end
37
+
38
+ class Module
39
+ def instance_method_with_additional_info(name)
40
+ returning instance_method_without_additional_info(name) do |unbound|
41
+ unbound.name = name.to_sym
42
+ unbound.owner = ancestors.find{|mod| mod.instance_methods(false).include? name.to_s}
43
+ end
44
+ end
45
+ alias_method_chain :instance_method, :additional_info
46
+ end
47
+ end
@@ -20,4 +20,28 @@ class Module
20
20
  private target
21
21
  end
22
22
  end unless method_defined? :alias_method_chain
23
+
24
+ alias_method :module_exec, :instance_exec unless method_defined? :module_exec
25
+ alias_method :class_exec, :module_exec unless method_defined? :class_exec
26
+
27
+ # Metaprogramming utility to make block optional.
28
+ # Tests first if block is already optional when given options
29
+ def make_block_optional(*methods)
30
+ options = methods.extract_options!
31
+ methods.each do |selector|
32
+ next unless method_defined? selector
33
+ unless options.empty?
34
+ test_on = options[:test_on] || self.new
35
+ next if (test_on.send(selector, *options.fetch(:arg, [])) rescue false)
36
+ end
37
+ alias_method_chain(selector, :optional_block) do |aliased_target, punctuation|
38
+ module_eval <<-end_eval
39
+ def #{aliased_target}_with_optional_block#{punctuation}(*args, &block)
40
+ return to_enum(:#{aliased_target}_without_optional_block#{punctuation}, *args) unless block_given?
41
+ #{aliased_target}_without_optional_block#{punctuation}(*args, &block)
42
+ end
43
+ end_eval
44
+ end
45
+ end
46
+ end
23
47
  end
@@ -1,6 +1,7 @@
1
1
  require 'enumerator'
2
2
 
3
- class Object
3
+ module Kernel # Did you know that object instance methods are defined in Kernel?
4
+
4
5
  # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/Object.html]
5
6
  def try(method_id, *args, &block)
6
7
  send(method_id, *args, &block) unless self.nil? #todo: check new def
@@ -19,4 +20,15 @@ class Object
19
20
  end unless method_defined? :returning
20
21
 
21
22
  Enumerator = Enumerable::Enumerator unless const_defined? :Enumerator # Standard in ruby 1.9
22
- end
23
+
24
+ def define_singleton_method(symbol, &block)
25
+ class << self
26
+ self
27
+ end.send(:define_method, symbol, block)
28
+ end unless method_defined? :define_singleton_method
29
+
30
+ def instance_exec(*arg, &block)
31
+ define_singleton_method(:"temporary method for instance_exec", &block)
32
+ send(:"temporary method for instance_exec", *arg)
33
+ end unless method_defined? :instance_exec
34
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module ObjectSpace
3
+ module_eval do
4
+ make_block_optional :each_object, :test_on => ObjectSpace
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ class Range
2
+ make_block_optional :each, :test_on => 69..666
3
+ make_block_optional :step, :test_on => 69..666, :arg => 42
4
+ end
@@ -0,0 +1,11 @@
1
+ class Regexp
2
+ class << self
3
+ unless (union(%w(a b)) rescue false)
4
+ def union_with_array_argument(*arg)
5
+ return union_without_array_argument(*arg) unless arg.size == 1
6
+ union_without_array_argument(*arg.first)
7
+ end
8
+ alias_method_chain :union, :array_argument
9
+ end
10
+ end
11
+ end
@@ -1,13 +1,93 @@
1
1
  class String
2
+ class << self
3
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
4
+ def try_convert(x)
5
+ return nil unless x.respond_do(:to_str)
6
+ x.to_str
7
+ end unless method_defined? :try_convert
8
+ end
9
+
10
+ def ascii_only?
11
+ !(self =~ /[^\x00-\x7f]/)
12
+ end unless method_defined? :ascii_only?
13
+
14
+ alias_method :bytesize, :length unless method_defined? :bytesize
15
+
16
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
17
+ def camelize(first_letter = :upper)
18
+ if first_letter == :upper
19
+ gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
20
+ else
21
+ first.downcase + camelize[1..-1]
22
+ end
23
+ end unless method_defined? :camelize
24
+
2
25
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
3
- def start_with?(*prefixes)
4
- prefixes.each do |prefix|
5
- prefix = prefix.to_s
6
- return true if self[0, prefix.length] == prefix
26
+ def chr
27
+ chars.first
28
+ end unless method_defined? :chr?
29
+
30
+
31
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
32
+ def clear
33
+ self[0,length] = ""
34
+ self
35
+ end unless method_defined? :clear?
36
+
37
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
38
+ def codepoints
39
+ return to_enum(:codepoints) unless block_given?
40
+ each_char.each do |s|
41
+ utf8 = s.each_byte.to_a
42
+ utf8[0] &= 0xff >> utf8.size # clear high bits (1 to 4, depending of number of bytes used)
43
+ yield utf8.inject{|result, b| (result << 6) + (b & 0x3f) }
7
44
  end
8
- false
9
- end unless method_defined? :start_with?
45
+ end unless method_defined? :codepoints
46
+
47
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
48
+ def constantize(camel_cased_word)
49
+ names = camel_cased_word.split('::')
50
+ names.shift if names.empty? || names.first.empty?
51
+
52
+ constant = Object
53
+ names.each do |name|
54
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
55
+ end
56
+ constant
57
+ end unless method_defined? :constantize
58
+
59
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
60
+ def dasherize(underscored_word)
61
+ underscored_word.gsub(/_/, '-')
62
+ end unless method_defined? :dasherize
63
+
64
+ # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
65
+ def demodulize(class_name_in_module)
66
+ class_name_in_module.to_s.gsub(/^.*::/, '')
67
+ end unless method_defined? :demodulize
68
+
69
+ make_block_optional :each_byte, :each, :each_line, :test_on => "abc"
70
+
71
+ unless ("abc".gsub(/./) rescue false)
72
+ def gsub_with_optional_block(*arg, &block)
73
+ return to_enum(:gsub_with_optional_block, *arg) unless block_given? || arg.size > 1
74
+ gsub_without_optional_block(*arg, &block)
75
+ end
76
+ alias_method_chain :gsub, :optional_block
77
+ end
78
+
79
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
80
+ unless method_defined? :each_char
81
+ def each_char(&block)
82
+ return to_enum(:each_char) unless block_given?
83
+ scan(/./, &block)
84
+ end
85
+
86
+ alias_method :chars, :each_char unless method_defined? :chars
87
+ end
10
88
 
89
+ alias_method :each_codepoint, :codepoints unless method_defined? :each_codepoint
90
+
11
91
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
12
92
  def end_with?(*suffixes)
13
93
  suffixes.each do |suffix|
@@ -22,17 +102,6 @@ class String
22
102
  self[i]
23
103
  end unless method_defined? :getbyte
24
104
 
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
- def each_char(&block)
28
- return to_enum(:each_char) unless block_given?
29
- scan(/./, &block)
30
- end
31
- end
32
-
33
- alias_method :chars, :each_char unless method_defined? :chars
34
-
35
-
36
105
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
37
106
  unless ("check partition".partition(" ") rescue false)
38
107
  def partition_with_new_meaning(*args, &block)
@@ -68,14 +137,14 @@ class String
68
137
  end unless method_defined? :rpartition
69
138
 
70
139
 
71
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
72
- def camelize(first_letter = :upper)
73
- if first_letter == :upper
74
- gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
75
- else
76
- first.downcase + camelize[1..-1]
140
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
141
+ def start_with?(*prefixes)
142
+ prefixes.each do |prefix|
143
+ prefix = prefix.to_s
144
+ return true if self[0, prefix.length] == prefix
77
145
  end
78
- end unless method_defined? :camelize
146
+ false
147
+ end unless method_defined? :start_with?
79
148
 
80
149
  # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
81
150
  def underscore(camel_cased_word)
@@ -86,26 +155,13 @@ class String
86
155
  downcase
87
156
  end unless method_defined? :underscore
88
157
 
89
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
90
- def constantize(camel_cased_word)
91
- names = camel_cased_word.split('::')
92
- names.shift if names.empty? || names.first.empty?
93
-
94
- constant = Object
95
- names.each do |name|
96
- constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
158
+ unless ("abc".upto("def", true) rescue false)
159
+ def upto_with_exclusive(to, excl=false, &block)
160
+ enum = Range.new(self, to, excl).to_enum
161
+ return enum unless block_given?
162
+ enum.each(&block)
163
+ self
97
164
  end
98
- constant
99
- end unless method_defined? :constantize
100
-
101
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
102
- def dasherize(underscored_word)
103
- underscored_word.gsub(/_/, '-')
104
- end unless method_defined? :dasherize
105
-
106
- # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
107
- def demodulize(class_name_in_module)
108
- class_name_in_module.to_s.gsub(/^.*::/, '')
109
- end unless method_defined? :demodulize
110
-
165
+ alias_method_chain :upto, :exclusive
166
+ end
111
167
  end
@@ -0,0 +1,3 @@
1
+ class Struct
2
+ make_block_optional :each, :each_pair, :test_on => Struct.new(:foo, :bar)
3
+ end
@@ -3,4 +3,18 @@ class Symbol
3
3
  def to_proc
4
4
  Proc.new { |*args| args.shift.__send__(self, *args) }
5
5
  end unless :to_proc.respond_to?(:to_proc)
6
+
7
+ include Enumerable
8
+
9
+ [ [%w(<=> casecmp), {:before => "return nil unless args.first.is_a? Symbol" }],
10
+ [%w(capitalize downcase next succ swapcase upcase), {:after => ".to_s"}],
11
+ [%w(=~ [] empty? length match size), {}]
12
+ ].each { |methods, options| methods.each do |method|
13
+ module_eval <<-end_eval
14
+ def #{method}(*args)
15
+ #{options[:before]}
16
+ to_s.#{method}(*args)#{options[:after]}
17
+ end unless method_defined? :#{method}
18
+ end_eval
19
+ end }
6
20
  end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class BindingTest < Test::Unit::TestCase
4
+ class Demo
5
+ def initialize(n)
6
+ @secret = n
7
+ end
8
+ def get_binding
9
+ return binding()
10
+ end
11
+ end
12
+
13
+ context "Binding" do
14
+ context "#eval" do
15
+ should "conform to doc" do
16
+ assert_equal 99, Demo.new(99).get_binding.eval("@secret")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -83,6 +83,16 @@ class EnumerableTest < Test::Unit::TestCase
83
83
  end
84
84
  end
85
85
 
86
+ context "#find" do
87
+ should "not require a block" do
88
+ assert_equal 3, (1..10).find.each {|item| item > 2 }
89
+ end
90
+
91
+ should "work as expected" do
92
+ assert_equal 3, (1..10).find {|item| item > 2 }
93
+ end
94
+ end
95
+
86
96
  context "#find_index" do
87
97
  should "conform to doc" do
88
98
  assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+
4
+ class EnumeratorTest < Test::Unit::TestCase
5
+ context "Enumerator" do
6
+ context "#with_object" do
7
+ should "conform to doc" do
8
+ animals = %w(cat dog wombat).to_enum
9
+ hash = animals.with_object({}).each do |item, memo|
10
+ memo[item] = item.upcase.reverse
11
+ end
12
+ assert_equal({"cat"=>"TAC", "dog"=>"GOD", "wombat"=>"TABMOW"}, hash)
13
+ end
14
+ end
15
+
16
+ context "#new" do
17
+ should "should accept block" do
18
+ enum = Enumerator.new do |yielder|
19
+ yielder.yield "This cool new syntax is sponsored by"
20
+ yielder.yield yielder.class
21
+ end
22
+ assert enum.is_a?(Enumerator)
23
+ 2.times do
24
+ assert_equal ["This cool new syntax is sponsored by", Enumerator::Yielder], enum.to_a
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ $outside = __callee__
4
+ def fred
5
+ "I'm in #{__callee__.inspect}"
6
+ end
7
+
8
+ class KernelTest < Test::Unit::TestCase
9
+ context "Kernel" do
10
+ context ".loop" do
11
+ should "conform to doc" do
12
+ enum1 = [1, 2, 3].to_enum
13
+ enum2 = [10, 20].to_enum
14
+ r = []
15
+ loop do
16
+ r << enum1.next + enum2.next
17
+ end
18
+ assert_equal [11,22], r
19
+ end
20
+ end
21
+
22
+
23
+ context ".__callee__" do
24
+ should "conform to doc" do
25
+ assert_equal "I'm in :fred", fred
26
+ assert_equal nil, $outside
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ require 'test_helper'
2
+
3
+ class ArrayTest < Test::Unit::TestCase
4
+
5
+ context "Method" do
6
+ setup do
7
+ @cat = "cat"
8
+ @bound = @cat.method(:upcase)
9
+ end
10
+
11
+ context "#name" do
12
+ should "conform to doc" do
13
+ assert_equal :upcase, @bound.name
14
+ end
15
+ end
16
+
17
+ context "#owner" do
18
+ should "conform to doc" do
19
+ assert_equal String, @bound.owner
20
+ end
21
+ end
22
+
23
+ context "#receiver" do
24
+ should "conform to doc" do
25
+ assert @cat === @bound.receiver
26
+ end
27
+ end
28
+
29
+ context "Unbound" do
30
+ setup do
31
+ @unbound = @bound.unbind
32
+ end
33
+
34
+ context "#name" do
35
+ should "conform to doc" do
36
+ assert_equal :upcase, @unbound.name
37
+ end
38
+ end
39
+
40
+ context "#owner" do
41
+ should "conform to doc" do
42
+ assert_equal String, @unbound.owner
43
+ end
44
+ end
45
+
46
+ context "bound again" do
47
+ setup do
48
+ @dog = "dog"
49
+ @bound_again = @unbound.bind(@dog)
50
+ end
51
+
52
+ context "#name" do
53
+ should "conform to doc" do
54
+ assert_equal :upcase, @bound_again.name
55
+ end
56
+ end
57
+
58
+ context "#owner" do
59
+ should "conform to doc" do
60
+ assert_equal String, @bound_again.owner
61
+ end
62
+ end
63
+
64
+ context "#receiver" do
65
+ should "conform to doc" do
66
+ assert @dog === @bound_again.receiver
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class Thing
4
+ end
5
+
6
+ class ModuleTest < Test::Unit::TestCase
7
+ context "Module" do
8
+ context "#module_exec" do
9
+ should "conform to doc" do
10
+ name = :new_instance_variable
11
+ Thing.module_exec(name) do |iv_name|
12
+ attr_accessor iv_name
13
+ end
14
+ t = Thing.new
15
+ t.new_instance_variable = "wibble"
16
+ assert_equal "wibble", t.new_instance_variable
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class ObjectTest < Test::Unit::TestCase
4
+ class KlassWithSecret
5
+ def initialize
6
+ @secret = 99
7
+ end
8
+ end
9
+ context "Object" do
10
+ context "#instance_exec" do
11
+ should "conform to doc" do
12
+ k = KlassWithSecret.new
13
+ assert_equal 104, k.instance_exec(5) {|x| @secret+x }
14
+ end
15
+ end
16
+
17
+ context "#define_singleton_method" do
18
+ should "conform to doc" do
19
+ a = "cat"
20
+ a.define_singleton_method(:speak) do
21
+ "miaow"
22
+ end
23
+ assert_equal "miaow", a.speak
24
+
25
+ KlassWithSecret.class_eval do
26
+ define_method(:one) { "instance method" }
27
+ define_singleton_method(:two) { "class method" }
28
+ end
29
+ t = KlassWithSecret.new
30
+ assert_equal "instance method", t.one
31
+ assert_equal "class method", KlassWithSecret.two
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class RegexpTest < Test::Unit::TestCase
4
+ context "Regexp" do
5
+ context ".union" do
6
+ should "conform to doc" do
7
+ assert_equal /cat/ , Regexp.union("cat")
8
+ assert_equal /cat|dog/ , Regexp.union("cat", "dog")
9
+ assert_equal /cat|dog/ , Regexp.union(%w{ cat dog })
10
+ assert_equal /cat|(?i-mx:dog)/, Regexp.union("cat", /dog/i)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -4,6 +4,14 @@ require 'test_helper'
4
4
 
5
5
  class StringTest < Test::Unit::TestCase
6
6
  context "String" do
7
+ context "#ascii_only?" do
8
+ should "conform to doc" do
9
+ assert_equal true, "dog".ascii_only?
10
+ assert_equal false, "δog".ascii_only?
11
+ assert_equal true, "\x00 to \x7f".ascii_only?
12
+ end
13
+ end
14
+
7
15
  context "#chars" do
8
16
  should "conform to doc" do
9
17
  assert_equal ["d", "o", "g"], "dog".chars.to_a
@@ -13,6 +21,23 @@ class StringTest < Test::Unit::TestCase
13
21
  assert_equal ["δ", "o", "g"], result
14
22
  end
15
23
  end
24
+
25
+ context "#chr" do
26
+ should "conform to doc" do
27
+ assert_equal "d", "dog".chr
28
+ assert_equal "δ", "δog".chr
29
+ end
30
+ end
31
+
32
+ context "#codepoints" do
33
+ should "conform to doc" do
34
+ assert_equal [100, 111, 103], "dog".codepoints.to_a
35
+ assert_equal [948, 111, 103], "δog".codepoints.to_a # Note, there is an error in Pragmatics' book
36
+ result = []
37
+ assert_equal "δog", "δog".codepoints.each {|b| result << b }
38
+ assert_equal [948, 111, 103], result
39
+ end
40
+ end
16
41
 
17
42
  context "#start_with" do
18
43
  should "conform to doc" do
@@ -6,5 +6,5 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
7
  require 'backports'
8
8
 
9
- class Test::Unit::TestCase
10
- end
9
+ # class Test::Unit::TestCase
10
+ # 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.5.0
4
+ version: 1.6.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-24 00:00:00 -04:00
12
+ date: 2009-04-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -30,17 +30,35 @@ files:
30
30
  - VERSION.yml
31
31
  - lib/backports.rb
32
32
  - lib/backports/array.rb
33
+ - lib/backports/binding.rb
34
+ - lib/backports/dir.rb
33
35
  - lib/backports/enumerable.rb
36
+ - lib/backports/enumerator.rb
34
37
  - lib/backports/fixnum.rb
35
38
  - lib/backports/hash.rb
39
+ - lib/backports/integer.rb
40
+ - lib/backports/io.rb
41
+ - lib/backports/kernel.rb
42
+ - lib/backports/method.rb
36
43
  - lib/backports/module.rb
37
44
  - lib/backports/object.rb
45
+ - lib/backports/object_space.rb
38
46
  - lib/backports/proc.rb
47
+ - lib/backports/range.rb
48
+ - lib/backports/regexp.rb
39
49
  - lib/backports/string.rb
50
+ - lib/backports/struct.rb
40
51
  - lib/backports/symbol.rb
41
52
  - test/array_test.rb
53
+ - test/binding_test.rb
42
54
  - test/enumerable_test.rb
55
+ - test/enumerator_test.rb
43
56
  - test/hash_test.rb
57
+ - test/kernel_test.rb
58
+ - test/method_test.rb
59
+ - test/module_test.rb
60
+ - test/object_test.rb
61
+ - test/regexp_test.rb
44
62
  - test/string_test.rb
45
63
  - test/test_helper.rb
46
64
  has_rdoc: true
@@ -77,7 +95,14 @@ specification_version: 2
77
95
  summary: Backports or ruby 1.8.7+ & rails for older ruby.
78
96
  test_files:
79
97
  - test/array_test.rb
98
+ - test/binding_test.rb
80
99
  - test/enumerable_test.rb
100
+ - test/enumerator_test.rb
81
101
  - test/hash_test.rb
102
+ - test/kernel_test.rb
103
+ - test/method_test.rb
104
+ - test/module_test.rb
105
+ - test/object_test.rb
106
+ - test/regexp_test.rb
82
107
  - test/string_test.rb
83
108
  - test/test_helper.rb