polyfill 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +26 -10
  5. data/CONTRIBUTING.md +0 -2
  6. data/README.md +107 -28
  7. data/lib/polyfill.rb +168 -74
  8. data/lib/polyfill/utils.rb +8 -3
  9. data/lib/polyfill/v2_2.rb +9 -0
  10. data/lib/polyfill/v2_2/enumerable.rb +34 -0
  11. data/lib/polyfill/v2_2/kernel.rb +9 -0
  12. data/lib/polyfill/v2_3.rb +2 -0
  13. data/lib/polyfill/v2_3/array.rb +22 -3
  14. data/lib/polyfill/v2_3/enumerable.rb +48 -3
  15. data/lib/polyfill/v2_3/enumerator/lazy.rb +7 -3
  16. data/lib/polyfill/v2_3/hash.rb +39 -3
  17. data/lib/polyfill/v2_3/kernel.rb +17 -0
  18. data/lib/polyfill/v2_3/string.rb +23 -5
  19. data/lib/polyfill/v2_3/struct.rb +22 -3
  20. data/lib/polyfill/v2_4/array.rb +25 -3
  21. data/lib/polyfill/v2_4/comparable.rb +9 -3
  22. data/lib/polyfill/v2_4/dir.rb +5 -3
  23. data/lib/polyfill/v2_4/enumerable.rb +28 -3
  24. data/lib/polyfill/v2_4/enumerator/lazy.rb +15 -3
  25. data/lib/polyfill/v2_4/file.rb +5 -3
  26. data/lib/polyfill/v2_4/float.rb +38 -3
  27. data/lib/polyfill/v2_4/hash.rb +35 -3
  28. data/lib/polyfill/v2_4/i_p_addr.rb +11 -3
  29. data/lib/polyfill/v2_4/integer.rb +53 -3
  30. data/lib/polyfill/v2_4/io.rb +166 -4
  31. data/lib/polyfill/v2_4/match_data.rb +11 -3
  32. data/lib/polyfill/v2_4/numeric.rb +15 -3
  33. data/lib/polyfill/v2_4/object.rb +9 -3
  34. data/lib/polyfill/v2_4/pathname.rb +7 -3
  35. data/lib/polyfill/v2_4/regexp.rb +3 -3
  36. data/lib/polyfill/v2_4/string.rb +110 -4
  37. data/lib/polyfill/v2_4/string_io.rb +166 -2
  38. data/lib/polyfill/v2_4/symbol.rb +17 -3
  39. data/lib/polyfill/version.rb +1 -1
  40. data/polyfill.gemspec +1 -1
  41. metadata +7 -98
  42. data/lib/polyfill/v2_3/array/instance.rb +0 -11
  43. data/lib/polyfill/v2_3/array/instance/dig.rb +0 -42
  44. data/lib/polyfill/v2_3/enumerable/instance.rb +0 -15
  45. data/lib/polyfill/v2_3/enumerable/instance/chunk_while.rb +0 -70
  46. data/lib/polyfill/v2_3/enumerable/instance/grep_v.rb +0 -48
  47. data/lib/polyfill/v2_3/enumerable/instance/slice_before.rb +0 -48
  48. data/lib/polyfill/v2_3/enumerator/lazy/instance.rb +0 -13
  49. data/lib/polyfill/v2_3/enumerator/lazy/instance/grep_v.rb +0 -31
  50. data/lib/polyfill/v2_3/hash/instance.rb +0 -15
  51. data/lib/polyfill/v2_3/hash/instance/dig.rb +0 -17
  52. data/lib/polyfill/v2_3/hash/instance/fetch_values.rb +0 -32
  53. data/lib/polyfill/v2_3/hash/instance/to_proc.rb +0 -23
  54. data/lib/polyfill/v2_3/string/class.rb +0 -11
  55. data/lib/polyfill/v2_3/string/class/new.rb +0 -33
  56. data/lib/polyfill/v2_3/string/instance.rb +0 -13
  57. data/lib/polyfill/v2_3/string/instance/minus_unary.rb +0 -23
  58. data/lib/polyfill/v2_3/string/instance/plus_unary.rb +0 -23
  59. data/lib/polyfill/v2_3/struct/instance.rb +0 -11
  60. data/lib/polyfill/v2_3/struct/instance/dig.rb +0 -17
  61. data/lib/polyfill/v2_4/array/instance.rb +0 -13
  62. data/lib/polyfill/v2_4/array/instance/concat.rb +0 -30
  63. data/lib/polyfill/v2_4/array/instance/sum.rb +0 -17
  64. data/lib/polyfill/v2_4/comparable/instance.rb +0 -11
  65. data/lib/polyfill/v2_4/comparable/instance/clamp.rb +0 -35
  66. data/lib/polyfill/v2_4/dir/class.rb +0 -11
  67. data/lib/polyfill/v2_4/dir/class/empty_q.rb +0 -23
  68. data/lib/polyfill/v2_4/enumerable/instance.rb +0 -15
  69. data/lib/polyfill/v2_4/enumerable/instance/chunk.rb +0 -48
  70. data/lib/polyfill/v2_4/enumerable/instance/sum.rb +0 -52
  71. data/lib/polyfill/v2_4/enumerable/instance/uniq.rb +0 -45
  72. data/lib/polyfill/v2_4/enumerator/lazy/instance.rb +0 -15
  73. data/lib/polyfill/v2_4/enumerator/lazy/instance/chunk_while.rb +0 -29
  74. data/lib/polyfill/v2_4/enumerator/lazy/instance/uniq.rb +0 -33
  75. data/lib/polyfill/v2_4/file/class.rb +0 -11
  76. data/lib/polyfill/v2_4/file/class/empty_q.rb +0 -23
  77. data/lib/polyfill/v2_4/float/instance.rb +0 -15
  78. data/lib/polyfill/v2_4/float/instance/ceil.rb +0 -32
  79. data/lib/polyfill/v2_4/float/instance/floor.rb +0 -32
  80. data/lib/polyfill/v2_4/float/instance/truncate.rb +0 -32
  81. data/lib/polyfill/v2_4/hash/instance.rb +0 -17
  82. data/lib/polyfill/v2_4/hash/instance/compact.rb +0 -23
  83. data/lib/polyfill/v2_4/hash/instance/compact_e.rb +0 -23
  84. data/lib/polyfill/v2_4/hash/instance/transform_values.rb +0 -33
  85. data/lib/polyfill/v2_4/hash/instance/transform_values_e.rb +0 -33
  86. data/lib/polyfill/v2_4/i_p_addr/instance.rb +0 -13
  87. data/lib/polyfill/v2_4/i_p_addr/instance/equalequal.rb +0 -27
  88. data/lib/polyfill/v2_4/i_p_addr/instance/lessthanequalgreaterthan.rb +0 -27
  89. data/lib/polyfill/v2_4/integer/instance.rb +0 -19
  90. data/lib/polyfill/v2_4/integer/instance/ceil.rb +0 -28
  91. data/lib/polyfill/v2_4/integer/instance/digits.rb +0 -34
  92. data/lib/polyfill/v2_4/integer/instance/floor.rb +0 -28
  93. data/lib/polyfill/v2_4/integer/instance/round.rb +0 -31
  94. data/lib/polyfill/v2_4/integer/instance/truncate.rb +0 -28
  95. data/lib/polyfill/v2_4/io/class.rb +0 -13
  96. data/lib/polyfill/v2_4/io/class/foreach.rb +0 -55
  97. data/lib/polyfill/v2_4/io/class/readlines.rb +0 -37
  98. data/lib/polyfill/v2_4/io/instance.rb +0 -19
  99. data/lib/polyfill/v2_4/io/instance/each_line.rb +0 -54
  100. data/lib/polyfill/v2_4/io/instance/gets.rb +0 -37
  101. data/lib/polyfill/v2_4/io/instance/lines.rb +0 -54
  102. data/lib/polyfill/v2_4/io/instance/readline.rb +0 -37
  103. data/lib/polyfill/v2_4/io/instance/readlines.rb +0 -37
  104. data/lib/polyfill/v2_4/match_data/instance.rb +0 -13
  105. data/lib/polyfill/v2_4/match_data/instance/named_captures.rb +0 -25
  106. data/lib/polyfill/v2_4/match_data/instance/values_at.rb +0 -25
  107. data/lib/polyfill/v2_4/numeric/instance.rb +0 -17
  108. data/lib/polyfill/v2_4/numeric/instance/clone.rb +0 -23
  109. data/lib/polyfill/v2_4/numeric/instance/dup.rb +0 -23
  110. data/lib/polyfill/v2_4/numeric/instance/finite_q.rb +0 -23
  111. data/lib/polyfill/v2_4/numeric/instance/infinite_q.rb +0 -23
  112. data/lib/polyfill/v2_4/object/instance.rb +0 -11
  113. data/lib/polyfill/v2_4/object/instance/clone.rb +0 -29
  114. data/lib/polyfill/v2_4/pathname/instance.rb +0 -11
  115. data/lib/polyfill/v2_4/pathname/instance/empty_q.rb +0 -29
  116. data/lib/polyfill/v2_4/regexp/instance.rb +0 -11
  117. data/lib/polyfill/v2_4/regexp/instance/match_q.rb +0 -23
  118. data/lib/polyfill/v2_4/string/class.rb +0 -11
  119. data/lib/polyfill/v2_4/string/class/new.rb +0 -26
  120. data/lib/polyfill/v2_4/string/instance.rb +0 -23
  121. data/lib/polyfill/v2_4/string/instance/casecmp_q.rb +0 -23
  122. data/lib/polyfill/v2_4/string/instance/concat.rb +0 -30
  123. data/lib/polyfill/v2_4/string/instance/each_line.rb +0 -17
  124. data/lib/polyfill/v2_4/string/instance/lines.rb +0 -55
  125. data/lib/polyfill/v2_4/string/instance/match_q.rb +0 -23
  126. data/lib/polyfill/v2_4/string/instance/prepend.rb +0 -30
  127. data/lib/polyfill/v2_4/string/instance/unpack1.rb +0 -23
  128. data/lib/polyfill/v2_4/string_io/instance.rb +0 -17
  129. data/lib/polyfill/v2_4/string_io/instance/each_line.rb +0 -17
  130. data/lib/polyfill/v2_4/string_io/instance/gets.rb +0 -17
  131. data/lib/polyfill/v2_4/string_io/instance/readline.rb +0 -17
  132. data/lib/polyfill/v2_4/string_io/instance/readlines.rb +0 -17
  133. data/lib/polyfill/v2_4/symbol/instance.rb +0 -15
  134. data/lib/polyfill/v2_4/symbol/instance/casecmp_q.rb +0 -25
  135. data/lib/polyfill/v2_4/symbol/instance/match.rb +0 -27
  136. data/lib/polyfill/v2_4/symbol/instance/match_q.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 378610a792ea5873a656859b5e1bd5d46402dd70
4
- data.tar.gz: d0d81f15485b7bc5de7f0480071aa32d90f583f2
3
+ metadata.gz: f89fe1c04a0c5226662965adf194eca6e5efb720
4
+ data.tar.gz: 714c012252e26b39e93e3967af657a1ba1a6b7f2
5
5
  SHA512:
6
- metadata.gz: c9a61e5c76de85f31c9ee24ec75e125102b78acd7ed235e1227c55e3792bacb6bf991eadc90f2695141e3978abdd8ce4720d00e137bf0a7e20197ae213e7ea7b
7
- data.tar.gz: f3b1f7bfd59f1fd341c061a05ce48804db9e933db5b8bad4e664473bcaf586a37cb1bb84e63c4f55dd60fde0271f2d57aa64362723263539327f3c9adac5ea51
6
+ metadata.gz: 518365852878a1fd4146557895021ecaeff61ae04804e5d386bf43623a8f5114e3cfc7fc8801c978654f83403cff56326fa63e55795cbc3b89fc3d4653a02ddb
7
+ data.tar.gz: 27082bfce68e460d5dc49697f6020194293631b5b1170653a1edf04bc8145e2d002e3027d110094ee238adf58d76aed0c7b4d29bfe7bc521c12a499453918945
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.2
2
+ TargetRubyVersion: 2.1
3
3
  Metrics/AbcSize:
4
4
  Enabled: false
5
5
  Metrics/BlockLength:
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.4.1
4
- - 2.3.3
5
- - 2.2.6
4
+ - 2.3.4
5
+ - 2.2.7
6
+ - 2.1.10
@@ -1,3 +1,16 @@
1
+ # [0.7.0][] (2017-04-22)
2
+
3
+ ## Changed
4
+
5
+ - Sending no parameters to `Polyfill()` now returns nothing instead of everything.
6
+
7
+ ## Added
8
+
9
+ - Support for Ruby 2.1
10
+ - v2.2 Enumerable#slice_after
11
+ - v2.2 Kernel#itself
12
+ - v2.3 Kernel#loop
13
+
1
14
  # [0.6.0][] (2017-04-06)
2
15
 
3
16
  ## Fix
@@ -56,6 +69,10 @@
56
69
 
57
70
  # [0.3.0][] (2017-03-19)
58
71
 
72
+ ## Changed
73
+
74
+ - New way to select methods that doesn't rely on knowing the module structure
75
+
59
76
  ## Added
60
77
 
61
78
  - v2.4 Dir.empty?
@@ -71,11 +88,14 @@
71
88
  - v2.4 StringIO#readline
72
89
  - v2.4 StringIO#readlines
73
90
 
74
- ## Changes
91
+ # [0.2.0][] (2017-03-17)
75
92
 
76
- - New way to select methods that doesn't rely on knowing the module structure
93
+ ## Changed
77
94
 
78
- # [0.2.0][] (2017-03-17)
95
+ - Modules are camel case instead of only uppercasing the first letter of the method name.
96
+ - Modules for predicate methods now end with `Q` instead of `__Q`.
97
+ - Modules for dangerous methods now end with `E` instead of `__E`.
98
+ - Methods will no longer attempt to fix `#respond_to?`, `#methods`, or `.instance_methods`. This will be revisited later with a more comprehensive solution.
79
99
 
80
100
  ## Added
81
101
 
@@ -86,13 +106,6 @@
86
106
  - v2.4 Hash#transform_values
87
107
  - v2.4 Hash#transform_values!
88
108
 
89
- ## Changes
90
-
91
- - Modules are camel case instead of only uppercasing the first letter of the method name.
92
- - Modules for predicate methods now end with `Q` instead of `__Q`.
93
- - Modules for dangerous methods now end with `E` instead of `__E`.
94
- - Methods will no longer attempt to fix `#respond_to?`, `#methods`, or `.instance_methods`. This will be revisited later with a more comprehensive solution.
95
-
96
109
  # [0.1.0][] (2017-03-14)
97
110
 
98
111
  - v2.4 Array#concat
@@ -110,6 +123,9 @@
110
123
  - v2.4 String#concat?
111
124
  - v2.4 String#prepend?
112
125
 
126
+ [0.7.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.6.0...v0.7.0
127
+ [0.6.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.5.0...v0.6.0
128
+ [0.5.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.4.0...v0.5.0
113
129
  [0.4.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.3.0...v0.4.0
114
130
  [0.3.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.2.0...v0.3.0
115
131
  [0.2.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.1.0...v0.2.0
@@ -12,8 +12,6 @@ A list of changes can be found at:
12
12
  * https://raw.githubusercontent.com/ruby/ruby/v2_4_1/NEWS
13
13
  * https://raw.githubusercontent.com/ruby/ruby/v2_3_4/NEWS
14
14
  * https://raw.githubusercontent.com/ruby/ruby/v2_2_7/NEWS
15
- * https://raw.githubusercontent.com/ruby/ruby/v2_1_10/NEWS
16
- * https://raw.githubusercontent.com/ruby/ruby/v2_0_0_648/NEWS
17
15
 
18
16
  Specific changes can be found by going to the [Ruby bug/feature tracker].
19
17
 
data/README.md CHANGED
@@ -10,15 +10,14 @@ code that would like newer features but is not completely ready to upgrade
10
10
  Ruby versions. The polyfills are built using refinements so there is **no
11
11
  monkey patching** that may cause issues outside of your use.
12
12
 
13
- Right now the only update is from 2.3 to 2.4 however the goal is to go all the way back to 2.0 (when refinements were introduced). Additionally, core methods are being focused on but stdlib will eventually be added.
14
-
15
13
  - [Caveat Emptor](#caveat-emptor)
16
14
  - [Installation](#installation)
17
15
  - [Goals](#goals)
18
16
  - [Usage](#usage)
19
17
  - [Implementation Table](#implementation-table)
20
- - [2.3 to 2.4](#23-to-24)
21
- - [2.2 to 2.3](#22-to-23)
18
+ - [2.4](#24)
19
+ - [2.3](#23)
20
+ - [2.2](#22)
22
21
 
23
22
  ## Caveat Emptor
24
23
 
@@ -34,7 +33,7 @@ See the [implementation table](#implementation-table) for specifics about what h
34
33
  Add it to your Gemfile:
35
34
 
36
35
  ```ruby
37
- gem 'polyfill', '0.6.0'
36
+ gem 'polyfill', '0.7.0'
38
37
  ```
39
38
 
40
39
  Or install it manually:
@@ -47,59 +46,63 @@ This project uses [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
47
46
 
48
47
  ## Goals
49
48
 
50
- 1. Features should ideally mimic the true behavior (including bugs).
49
+ 1. Features should ideally mimic the true behavior (including bugs, error messages, etc).
51
50
  2. Features should not significantly burden the runtime.
52
51
  3. Keep everything modular so users can be specific or broad in their usage.
53
52
 
54
53
  ## Usage
55
54
 
56
- To use all updates:
57
-
58
- ```ruby
59
- using Polyfill
60
- ```
61
-
62
- To specify methods from a particular object use it's class name and pass an
63
- array of strings containing the methods you'd like to use. Instance methods
64
- need to start with "#" and class methods need to start with ".".
55
+ With the `Polyfill` method, you can polyfill methods for one or more Ruby
56
+ objects. Each object is passed as a key. The value is an array of strings
57
+ containing the methods you would like to polyfill. Instance methods need to
58
+ start with '#' and class methods need to start with '.'.
65
59
 
66
60
  ```ruby
67
61
  using Polyfill(
68
62
  Array: %w[#concat],
69
63
  Dir: %w[.empty?],
70
- Hash: %w[#compact! #transform_values],
64
+ Hash: %w[#compact! #transform_values]
71
65
  )
72
66
  ```
73
67
 
74
- If you want all of the methods for a particular class you can use `:all`.
68
+ If you want all of the methods for a particular object you can use `:all` in
69
+ place of the array.
75
70
 
76
71
  ```ruby
77
72
  using Polyfill(Numeric: :all)
78
73
  ```
79
74
 
80
- Updates can be stopped at a specific version by pass it via `:version`. The
81
- version selected must be formatted as "MAJOR.MINOR".
75
+ Polyfills can be halted at a maximum version with the `:version` option. The
76
+ version must be a string with the major and minor version only.
82
77
 
83
78
  ```ruby
84
79
  using Polyfill(version: '2.3', Numeric: :all)
85
80
  ```
86
81
 
87
- Methods can be included in the same way. Prior to Ruby 2.4, refinements did
88
- not work on modules. In order to get methods you'll need to include them after
89
- the module. Calling `using` on a module will add it to all core Ruby classes
90
- that include it. The methods will only be included if they are needed by the
91
- Ruby version running the code.
82
+ When you add a method it will not be available in all of the ways a normal
83
+ method is. For example, you can't call `send` on a refined method prior to
84
+ Ruby 2.4. To gain back some of this support you can set `native: true`.
85
+ This currently adds support for `respond_to?`, `__send__`, and `send`.
86
+
87
+ ```ruby
88
+ using Polyfill(native: true, Numeric: :all)
89
+ ```
90
+
91
+ Prior to Ruby 2.4, refinements do not work on Modules. When using a polyfill
92
+ on a module it will instead refine the core classes that use the module. If
93
+ you're building your own class, it will not receive the polyfill. Instead,
94
+ you can add the polyfill by using `include`.
92
95
 
93
96
  ```ruby
94
97
  class Foo
95
98
  include Comparable
96
- include Polyfill(Comparable: %w[#clamp])
99
+ include Polyfill(Comparable: :all)
97
100
  end
98
101
  ```
99
102
 
100
103
  ## Implementation Table
101
104
 
102
- ### 2.3 to 2.4
105
+ ### 2.4
103
106
 
104
107
  | Object | Method | Implemented | Notes |
105
108
  | ---------------- | ------------------------ | ----------- | ----- |
@@ -108,6 +111,7 @@ end
108
111
  | | #min | No | This method already existed but was inherited from `Enumerable`. It was optimized on `Array` so redefining `Enumerable#min` no longer affects this.
109
112
  | | #pack | No |
110
113
  | | #sum | Yes |
114
+ | BasicObject | #__send__ | No |
111
115
  | Binding | #irb | No |
112
116
  | Comparable | #clamp | Yes |
113
117
  | CSV | #new | No |
@@ -141,6 +145,7 @@ end
141
145
  | | .readlines | Yes |
142
146
  | IPAddr | #== | Yes |
143
147
  | | #<=> | Yes |
148
+ | Kernel | #send | No |
144
149
  | Logger | #new | No |
145
150
  | MatchData | #named_captures | Yes |
146
151
  | | #values_at | Yes |
@@ -197,6 +202,7 @@ end
197
202
  | | #match? | Yes |
198
203
  | | #swapcase | No |
199
204
  | | #swapcase! | No |
205
+ | | #to_proc | No |
200
206
  | | #upcase | No |
201
207
  | | #upcase! | No |
202
208
  | Thread | #report\_on\_exception | No |
@@ -204,7 +210,7 @@ end
204
210
  | TracePoint | #callee_id | No |
205
211
  | Warning | #warn | No |
206
212
 
207
- ### 2.2 to 2.3
213
+ ### 2.3
208
214
 
209
215
  | Object | Method | Implemented | Notes |
210
216
  | ----------------------- | ------------------------ | ----------- | ----- |
@@ -242,7 +248,7 @@ end
242
248
  | | #close | No |
243
249
  | | #each_codepoint | No |
244
250
  | | #wait_readable | No |
245
- | Kernel | #loop | No |
251
+ | Kernel | #loop | Yes |
246
252
  | Logger | #level= | No |
247
253
  | | #reopen | No |
248
254
  | Module | #define_method | No |
@@ -279,6 +285,79 @@ end
279
285
  | UNIXServer | #accept_nonblock | No |
280
286
  | Vector | #round | No |
281
287
 
288
+ ### 2.2
289
+
290
+ | Object | Method | Implemented | Notes |
291
+ | ---------- | --------------------------------------- | ----------- | ----- |
292
+ | Binding | #local_variables | No |
293
+ | | #receiver | No |
294
+ | Dir | #fileno | No |
295
+ | Enumerable | #max | No |
296
+ | | #max_by | No |
297
+ | | #min | No |
298
+ | | #min_by | No |
299
+ | | #slice_after | Yes |
300
+ | | #slice_when | No |
301
+ | Etc | .confstr | No |
302
+ | | .sysconf | No |
303
+ | | .nprocessors | No |
304
+ | | .uname | No |
305
+ | Float | #next_float | No |
306
+ | | #prev_float | No |
307
+ | File | .birthtime | No |
308
+ | | #birthtime | No |
309
+ | | .find | No |
310
+ | | #find | No |
311
+ | File::Stat | #birthtime | No |
312
+ | GC | .latest_gc_info | No |
313
+ | | .stat | No |
314
+ | IO | #each_codepoint | No |
315
+ | | #nonblock_read | No |
316
+ | | #nonblock_write | No |
317
+ | | #pathconf | No |
318
+ | Kernel | #itself | Yes |
319
+ | | #throw | No |
320
+ | Math | .atan2 | No |
321
+ | | .log | No |
322
+ | Matrix | #+@ | No |
323
+ | | #-@ | No |
324
+ | | #adjugate | No |
325
+ | | #cofactor | No |
326
+ | | #first_minor | No |
327
+ | | .hstack | No |
328
+ | | #hstack | No |
329
+ | | #laplace_expansion | No |
330
+ | | .vstack | No |
331
+ | | #vstack | No |
332
+ | Method | #curry | No |
333
+ | | #super_method | No |
334
+ | ObjectSpace | .memsize_of | No |
335
+ | Pathname | #/ | No |
336
+ | | #birthtime | No |
337
+ | | #find | No |
338
+ | Prime | .prime? | No |
339
+ | Process | .spawn | No |
340
+ | String | #unicode_normalize | No |
341
+ | | #unicode_normalize! | No |
342
+ | | #unicode_normalized? | No |
343
+ | Time | .httpdate | No |
344
+ | | .parse | No |
345
+ | | .rfc2822 | No |
346
+ | | .strptime | No |
347
+ | | .xmlschema | No |
348
+ | TSort | .each_strongly_connected_component | No |
349
+ | | .each_strongly_connected_component_from | No |
350
+ | | .tsort_each | No |
351
+ | Vector | #+@ | No |
352
+ | | #-@ | No |
353
+ | | #angle_with | No |
354
+ | | .basis | No |
355
+ | | #cross | No |
356
+ | | #cross_product | No |
357
+ | | #dot | No |
358
+ | | .independent? | No |
359
+ | | #independent? | No |
360
+
282
361
  ## Contributing
283
362
 
284
363
  Bug reports and pull requests are welcome on GitHub at https://github.com/AaronLasseigne/polyfill.
@@ -1,22 +1,23 @@
1
+ require 'ipaddr'
2
+ require 'stringio'
1
3
  require 'polyfill/version'
2
4
  require 'polyfill/utils'
3
- require 'polyfill/v2_3'
4
- require 'polyfill/v2_4'
5
5
 
6
6
  module Polyfill
7
- include V2_3
8
- include V2_4
9
-
10
7
  module Parcel; end
11
8
  end
12
9
 
13
- def Polyfill(options) # rubocop:disable Style/MethodName
10
+ def Polyfill(options = {}) # rubocop:disable Style/MethodName
14
11
  mod = Module.new
15
12
 
13
+ #
14
+ # parse options
15
+ #
16
16
  objects, others = options.partition { |key,| key[/\A[A-Z]/] }
17
17
  others = others.to_h
18
18
 
19
19
  versions = {
20
+ '2.2' => Polyfill::V2_2,
20
21
  '2.3' => Polyfill::V2_3,
21
22
  '2.4' => Polyfill::V2_4
22
23
  }
@@ -28,91 +29,171 @@ def Polyfill(options) # rubocop:disable Style/MethodName
28
29
  version_number > desired_version
29
30
  end
30
31
 
32
+ native = others.delete(:native) { false }
33
+
31
34
  unless others.empty?
32
35
  raise ArgumentError, "unknown keyword: #{others.first[0]}"
33
36
  end
34
37
 
38
+ #
39
+ # useful vars
40
+ #
35
41
  current_ruby_version = RUBY_VERSION[/\A(\d+\.\d+)/, 1]
42
+ all_instance_modules = []
43
+
44
+ objects.each do |full_name, methods|
45
+ #
46
+ # find all polyfills for the object across all versions
47
+ #
48
+ object_module_names = full_name.to_s.split('::')
49
+
50
+ object_modules = versions
51
+ .map do |version_number, version_module|
52
+ begin
53
+ final_module = object_module_names
54
+ .reduce(version_module) do |current_mod, name|
55
+ current_mod.const_get(name, false)
56
+ end
36
57
 
37
- if objects.empty?
38
- mod.module_eval do
39
- versions.each do |_, object_module|
40
- include object_module
58
+ [version_number, final_module]
59
+ rescue NameError
60
+ nil
61
+ end
41
62
  end
42
- end
43
- else
44
- objects.each do |full_name, methods|
45
- object_module_names = full_name.to_s.split('::')
46
-
47
- object_modules = versions
48
- .map do |version_number, version_module|
49
- begin
50
- final_module = object_module_names
51
- .reduce(version_module) do |current_mod, name|
52
- current_mod.const_get(name, false)
53
- end
63
+ .compact
54
64
 
55
- [version_number, final_module]
56
- rescue NameError
57
- nil
58
- end
59
- end
60
- .compact
65
+ if object_modules.empty?
66
+ raise ArgumentError, %Q("#{full_name}" is not a valid class or has no updates)
67
+ end
61
68
 
62
- if object_modules.empty?
63
- raise ArgumentError, %Q("#{full_name}" is not a valid class or has no updates)
69
+ #
70
+ # get all class modules and instance modules from the polyfills
71
+ #
72
+ class_modules = object_modules.map do |version_number, object_module|
73
+ begin
74
+ [version_number, object_module.const_get(:ClassMethods, false).clone]
75
+ rescue NameError
76
+ nil
64
77
  end
78
+ end.compact
79
+ instance_modules = object_modules.map do |version_number, object_module|
80
+ [version_number, object_module.clone]
81
+ end
65
82
 
66
- if methods == :all
67
- mod.module_eval do
68
- object_modules.each do |version_number, object_module|
69
- include object_module if version_number > current_ruby_version
70
- end
71
- end
83
+ #
84
+ # get all requested class and instance methods
85
+ #
86
+ if methods != :all && (method_name = methods.find { |method| method !~ /\A[.#]/ })
87
+ raise ArgumentError, %Q("#{method_name}" must start with a "." if it's a class method or "#" if it's an instance method)
88
+ end
89
+
90
+ all_methods_for = lambda do |modules|
91
+ modules.flat_map { |_, m| m.instance_methods }.uniq
92
+ end
93
+ available_class_methods = all_methods_for.call(class_modules)
94
+ available_instance_methods = all_methods_for.call(instance_modules)
95
+
96
+ select_and_clean = lambda do |leader|
97
+ methods.select { |method| method.start_with?(leader) }.map { |method| method[1..-1].to_sym }
98
+ end
99
+ requested_class_methods = methods == :all ? available_class_methods : select_and_clean.call('.')
100
+ requested_instance_methods = methods == :all ? available_instance_methods : select_and_clean.call('#')
101
+
102
+ unless (leftovers = (requested_class_methods - available_class_methods)).empty?
103
+ raise ArgumentError, %Q(".#{leftovers.first}" is not a valid method on #{full_name} or has no updates)
104
+ end
105
+ unless (leftovers = (requested_instance_methods - available_instance_methods)).empty?
106
+ raise ArgumentError, %Q("##{leftovers.first}" is not a valid method on #{full_name} or has no updates)
107
+ end
108
+
109
+ #
110
+ # get the class(es) to refine
111
+ #
112
+ base_class = object_modules.first.last.name.sub(/\APolyfill::V\d_\d::/, '')
113
+ base_classes =
114
+ case base_class
115
+ when 'Comparable'
116
+ %w[Numeric String Time]
117
+ when 'Enumerable'
118
+ %w[Array Dir Enumerator Hash IO Range StringIO Struct]
119
+ when 'Kernel'
120
+ %w[Object]
72
121
  else
73
- methods.each do |method|
74
- type =
75
- case method[0]
76
- when '.'
77
- :Class
78
- when '#'
79
- :Instance
80
- else
81
- raise ArgumentError, %Q("#{method}" must start with a "." if it's a class method or "#" if it's an instance method)
82
- end
122
+ [base_class]
123
+ end
124
+
125
+ #
126
+ # refine in class methods
127
+ #
128
+ class_modules.each do |version_number, class_module|
129
+ next if version_number <= current_ruby_version
83
130
 
84
- method_name = method[1..-1]
85
- symbol_conversions = {
86
- '-' => 'minus', # must come first otherwise it creates a range in the regexp
87
- '+' => 'plus',
88
- '@' => '_unary',
89
- '=' => 'equal',
90
- '<' => 'lessthan',
91
- '>' => 'greaterthan',
92
- '?' => '_q',
93
- '!' => '_e'
94
- }
95
- method_name.gsub!(/[#{symbol_conversions.keys.join}]/o, symbol_conversions)
96
- method_name.capitalize!
97
- method_name.gsub!(/_(.)/) { |match| match[1].capitalize }
98
-
99
- method_modules = object_modules
100
- .map do |version_number, object_module|
101
- begin
102
- [version_number, object_module.const_get(type, false).const_get(method_name, false)]
103
- rescue NameError
104
- nil
131
+ class_module.instance_methods.each do |name|
132
+ class_module.send(:remove_method, name) unless requested_class_methods.include?(name)
133
+ end
134
+
135
+ next if class_module.instance_methods.empty?
136
+
137
+ mod.module_exec(requested_class_methods) do |methods_added|
138
+ base_classes.each do |klass|
139
+ refine Object.const_get(klass).singleton_class do
140
+ include class_module
141
+
142
+ if native
143
+ Polyfill::Utils.ignore_warnings do
144
+ define_method :respond_to? do |name, include_all = false|
145
+ return true if methods_added.include?(name)
146
+
147
+ super(name, include_all)
148
+ end
149
+
150
+ define_method :__send__ do |name, *args, &block|
151
+ return super(name, *args, &block) unless methods_added.include?(name)
152
+
153
+ class_module.instance_method(name).bind(self).call(*args, &block)
154
+ end
155
+ alias_method :send, :__send__
105
156
  end
106
157
  end
107
- .compact
108
-
109
- if method_modules.empty?
110
- raise ArgumentError, %Q("#{method}" is not a valid method on #{full_name} or has no updates)
111
158
  end
159
+ end
160
+ end
161
+ end
162
+
163
+ #
164
+ # refine in instance methods
165
+ #
166
+ instance_modules.each do |version_number, instance_module|
167
+ next if version_number <= current_ruby_version
168
+
169
+ instance_module.instance_methods.each do |name|
170
+ instance_module.send(:remove_method, name) unless requested_instance_methods.include?(name)
171
+ end
112
172
 
113
- mod.module_eval do
114
- method_modules.each do |version_number, method_module|
115
- include method_module if version_number > current_ruby_version
173
+ next if instance_module.instance_methods.empty?
174
+
175
+ all_instance_modules << instance_module
176
+
177
+ mod.module_exec(requested_instance_methods) do |methods_added|
178
+ base_classes.each do |klass|
179
+ refine Object.const_get(klass) do
180
+ include instance_module
181
+
182
+ if native
183
+ Polyfill::Utils.ignore_warnings do
184
+ define_method :respond_to? do |name, include_all = false|
185
+ return super(name, include_all) unless methods_added.include?(name)
186
+
187
+ true
188
+ end
189
+
190
+ define_method :__send__ do |name, *args, &block|
191
+ return super(name, *args, &block) unless methods_added.include?(name)
192
+
193
+ instance_module.instance_method(name).bind(self).call(*args, &block)
194
+ end
195
+ alias_method :send, :__send__
196
+ end
116
197
  end
117
198
  end
118
199
  end
@@ -120,5 +201,18 @@ def Polyfill(options) # rubocop:disable Style/MethodName
120
201
  end
121
202
  end
122
203
 
204
+ #
205
+ # make sure the includes get added if this module is included
206
+ #
207
+ mod.singleton_class.send(:define_method, :included) do |base|
208
+ all_instance_modules.each do |instance_module|
209
+ base.include instance_module
210
+ end
211
+ end
212
+
123
213
  Polyfill::Parcel.const_set("O#{mod.object_id}", mod)
124
214
  end
215
+
216
+ require 'polyfill/v2_2'
217
+ require 'polyfill/v2_3'
218
+ require 'polyfill/v2_4'