polyfill 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +30 -7
- data/Rakefile +3 -1
- data/lib/polyfill.rb +104 -14
- data/lib/polyfill/v2_2/enumerable.rb +20 -9
- data/lib/polyfill/v2_3/enumerable.rb +8 -24
- data/lib/polyfill/v2_4/array.rb +7 -7
- data/lib/polyfill/v2_4/enumerable.rb +5 -6
- data/lib/polyfill/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce45400dde62a6c4481017080a3770fe3557619e
|
4
|
+
data.tar.gz: 29d853335b679ed69d51df345786021e8919b121
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f9a80ce2cc37783a1060d403317eb5e142c6c1a97a81057fc4123c9c7d8e7fcf6fcbec1f40d130d43ef8ad737df0db2f55c09b62f2a10de674d815d88b01f2d
|
7
|
+
data.tar.gz: e465ec4b46c0ba099cfd5121402e6366eeca20991f6c00d03656127b0cfb6fe36159f5fd87d955655282e0bc076025d69a1622e10357f81996c7e3bd2ec6525b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
# [0.8.0][] (2017-04-27)
|
2
|
+
|
3
|
+
## Changed
|
4
|
+
|
5
|
+
- `Polyfill()` is no longer used with `include` or `extend`. Instead `Polyfill.get` should
|
6
|
+
be used.
|
7
|
+
|
8
|
+
## Added
|
9
|
+
|
10
|
+
- Polyfill.get for getting modules to include or extend
|
11
|
+
- v2.2 Enumerable#slice_when
|
12
|
+
|
13
|
+
## Fixed
|
14
|
+
|
15
|
+
- v2.3 Enumerable#chunk_while and v2.2 Enumerable#slice_after should not require `count`
|
16
|
+
- v2.4 Array#sum should not use `each` (the Enumerable version does)
|
17
|
+
- load modules before classes so they don't override the local method
|
18
|
+
|
1
19
|
# [0.7.0][] (2017-04-22)
|
2
20
|
|
3
21
|
## Changed
|
@@ -123,6 +141,7 @@
|
|
123
141
|
- v2.4 String#concat?
|
124
142
|
- v2.4 String#prepend?
|
125
143
|
|
144
|
+
[0.8.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.7.0...v0.8.0
|
126
145
|
[0.7.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.6.0...v0.7.0
|
127
146
|
[0.6.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.5.0...v0.6.0
|
128
147
|
[0.5.0]: https://github.com/AaronLasseigne/polyfill/compare/v0.4.0...v0.5.0
|
data/README.md
CHANGED
@@ -33,7 +33,7 @@ See the [implementation table](#implementation-table) for specifics about what h
|
|
33
33
|
Add it to your Gemfile:
|
34
34
|
|
35
35
|
```ruby
|
36
|
-
gem 'polyfill', '0.
|
36
|
+
gem 'polyfill', '0.8.0'
|
37
37
|
```
|
38
38
|
|
39
39
|
Or install it manually:
|
@@ -52,6 +52,8 @@ This project uses [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
52
52
|
|
53
53
|
## Usage
|
54
54
|
|
55
|
+
### Polyfill
|
56
|
+
|
55
57
|
With the `Polyfill` method, you can polyfill methods for one or more Ruby
|
56
58
|
objects. Each object is passed as a key. The value is an array of strings
|
57
59
|
containing the methods you would like to polyfill. Instance methods need to
|
@@ -88,15 +90,37 @@ This currently adds support for `respond_to?`, `__send__`, and `send`.
|
|
88
90
|
using Polyfill(native: true, Numeric: :all)
|
89
91
|
```
|
90
92
|
|
93
|
+
### Polyfill.get
|
94
|
+
|
91
95
|
Prior to Ruby 2.4, refinements do not work on Modules. When using a polyfill
|
92
96
|
on a module it will instead refine the core classes that use the module. If
|
93
97
|
you're building your own class, it will not receive the polyfill. Instead,
|
94
|
-
you can
|
98
|
+
you can `include` (or `extend`) in a polyfill with `Polyfill.get`.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
class Foo
|
102
|
+
include Comparable
|
103
|
+
include Polyfill.get(:Comparable, :all)
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
To use specific methods you can pass an array of symbols in place of `:all`.
|
95
108
|
|
96
109
|
```ruby
|
97
110
|
class Foo
|
98
111
|
include Comparable
|
99
|
-
include Polyfill(Comparable
|
112
|
+
include Polyfill.get(:Comparable, %i[clamp])
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
Like before, the polyfills can be halted at a maximum version with the
|
117
|
+
`:version` option. The version must be a string with the major and minor
|
118
|
+
version only.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
class Foo
|
122
|
+
include Comparable
|
123
|
+
include Polyfill.get(:Comparable, :all, version: '2.3')
|
100
124
|
end
|
101
125
|
```
|
102
126
|
|
@@ -111,7 +135,7 @@ end
|
|
111
135
|
| | #min | No | This method already existed but was inherited from `Enumerable`. It was optimized on `Array` so redefining `Enumerable#min` no longer affects this.
|
112
136
|
| | #pack | No |
|
113
137
|
| | #sum | Yes |
|
114
|
-
| BasicObject |
|
138
|
+
| BasicObject | #\_\_send\_\_ | No |
|
115
139
|
| Binding | #irb | No |
|
116
140
|
| Comparable | #clamp | Yes |
|
117
141
|
| CSV | #new | No |
|
@@ -297,7 +321,7 @@ end
|
|
297
321
|
| | #min | No |
|
298
322
|
| | #min_by | No |
|
299
323
|
| | #slice_after | Yes |
|
300
|
-
| | #slice_when |
|
324
|
+
| | #slice_when | Yes |
|
301
325
|
| Etc | .confstr | No |
|
302
326
|
| | .sysconf | No |
|
303
327
|
| | .nprocessors | No |
|
@@ -306,9 +330,8 @@ end
|
|
306
330
|
| | #prev_float | No |
|
307
331
|
| File | .birthtime | No |
|
308
332
|
| | #birthtime | No |
|
309
|
-
| | .find | No |
|
310
|
-
| | #find | No |
|
311
333
|
| File::Stat | #birthtime | No |
|
334
|
+
| Find | .find | No |
|
312
335
|
| GC | .latest_gc_info | No |
|
313
336
|
| | .stat | No |
|
314
337
|
| IO | #each_codepoint | No |
|
data/Rakefile
CHANGED
data/lib/polyfill.rb
CHANGED
@@ -5,6 +5,99 @@ require 'polyfill/utils'
|
|
5
5
|
|
6
6
|
module Polyfill
|
7
7
|
module Parcel; end
|
8
|
+
|
9
|
+
def get(module_name, methods, options = {})
|
10
|
+
if Object.const_get(module_name.to_s).is_a?(Class)
|
11
|
+
raise ArgumentError, "#{module_name} is a class not a module"
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# parse options
|
16
|
+
#
|
17
|
+
versions = {
|
18
|
+
'2.2' => Polyfill::V2_2,
|
19
|
+
'2.3' => Polyfill::V2_3,
|
20
|
+
'2.4' => Polyfill::V2_4
|
21
|
+
}
|
22
|
+
desired_version = options.delete(:version) || versions.keys.max
|
23
|
+
unless versions.keys.include?(desired_version)
|
24
|
+
raise ArgumentError, "invalid value for keyword version: #{desired_version}"
|
25
|
+
end
|
26
|
+
versions.reject! do |version_number, _|
|
27
|
+
version_number > desired_version
|
28
|
+
end
|
29
|
+
|
30
|
+
unless options.empty?
|
31
|
+
raise ArgumentError, "unknown keyword: #{options.first[0]}"
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# find all polyfills for the module across all versions
|
36
|
+
#
|
37
|
+
module_names = module_name.to_s.split('::')
|
38
|
+
current_ruby_version = RUBY_VERSION[/\A(\d+\.\d+)/, 1]
|
39
|
+
|
40
|
+
modules_with_updates = []
|
41
|
+
modules = []
|
42
|
+
versions.each do |version_number, version_module|
|
43
|
+
begin
|
44
|
+
final_module = module_names
|
45
|
+
.reduce(version_module) do |current_mod, name|
|
46
|
+
current_mod.const_get(name, false)
|
47
|
+
end
|
48
|
+
|
49
|
+
modules_with_updates << final_module
|
50
|
+
|
51
|
+
next if version_number <= current_ruby_version
|
52
|
+
|
53
|
+
modules << final_module.clone
|
54
|
+
rescue NameError
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
if modules_with_updates.empty?
|
60
|
+
raise ArgumentError, %Q("#{module_name}" has no updates)
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# remove methods that were not requested
|
65
|
+
#
|
66
|
+
methods_with_updates = modules_with_updates.flat_map(&:instance_methods).uniq
|
67
|
+
requested_methods = methods == :all ? methods_with_updates : methods
|
68
|
+
|
69
|
+
unless (leftovers = (requested_methods - methods_with_updates)).empty?
|
70
|
+
raise ArgumentError, %Q("##{leftovers.first}" is not a valid method on #{module_name} or has no updates)
|
71
|
+
end
|
72
|
+
|
73
|
+
modules.each do |instance_module|
|
74
|
+
instance_module.instance_methods.each do |name|
|
75
|
+
instance_module.send(:remove_method, name) unless requested_methods.include?(name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# build the module to return
|
81
|
+
#
|
82
|
+
mod = Module.new
|
83
|
+
|
84
|
+
# make sure the methods get added if this module is included
|
85
|
+
mod.singleton_class.send(:define_method, :included) do |base|
|
86
|
+
modules.each do |module_to_add|
|
87
|
+
base.include module_to_add unless module_to_add.instance_methods.empty?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# make sure the methods get added if this module is extended
|
92
|
+
mod.singleton_class.send(:define_method, :extended) do |base|
|
93
|
+
modules.each do |module_to_add|
|
94
|
+
base.extend module_to_add unless module_to_add.instance_methods.empty?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
Polyfill::Parcel.const_set("O#{mod.object_id}", mod)
|
99
|
+
end
|
100
|
+
module_function :get
|
8
101
|
end
|
9
102
|
|
10
103
|
def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
@@ -14,6 +107,15 @@ def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
|
14
107
|
# parse options
|
15
108
|
#
|
16
109
|
objects, others = options.partition { |key,| key[/\A[A-Z]/] }
|
110
|
+
objects.sort! do |a, b|
|
111
|
+
if !a.is_a?(Class) && b.is_a?(Class)
|
112
|
+
-1
|
113
|
+
elsif a.is_a?(Class) && !b.is_a?(Class)
|
114
|
+
1
|
115
|
+
else
|
116
|
+
0
|
117
|
+
end
|
118
|
+
end
|
17
119
|
others = others.to_h
|
18
120
|
|
19
121
|
versions = {
|
@@ -36,10 +138,9 @@ def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
|
36
138
|
end
|
37
139
|
|
38
140
|
#
|
39
|
-
# useful
|
141
|
+
# useful var
|
40
142
|
#
|
41
143
|
current_ruby_version = RUBY_VERSION[/\A(\d+\.\d+)/, 1]
|
42
|
-
all_instance_modules = []
|
43
144
|
|
44
145
|
objects.each do |full_name, methods|
|
45
146
|
#
|
@@ -63,7 +164,7 @@ def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
|
63
164
|
.compact
|
64
165
|
|
65
166
|
if object_modules.empty?
|
66
|
-
raise ArgumentError, %Q("#{full_name}" is not a valid
|
167
|
+
raise ArgumentError, %Q("#{full_name}" is not a valid object or has no updates)
|
67
168
|
end
|
68
169
|
|
69
170
|
#
|
@@ -172,8 +273,6 @@ def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
|
172
273
|
|
173
274
|
next if instance_module.instance_methods.empty?
|
174
275
|
|
175
|
-
all_instance_modules << instance_module
|
176
|
-
|
177
276
|
mod.module_exec(requested_instance_methods) do |methods_added|
|
178
277
|
base_classes.each do |klass|
|
179
278
|
refine Object.const_get(klass) do
|
@@ -201,15 +300,6 @@ def Polyfill(options = {}) # rubocop:disable Style/MethodName
|
|
201
300
|
end
|
202
301
|
end
|
203
302
|
|
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
|
-
|
213
303
|
Polyfill::Parcel.const_set("O#{mod.object_id}", mod)
|
214
304
|
end
|
215
305
|
|
@@ -6,27 +6,38 @@ module Polyfill
|
|
6
6
|
raise ArgumentError, 'wrong number of arguments (given 0, expected 1)' if !pattern && !block_given?
|
7
7
|
|
8
8
|
matcher = pattern || ::Proc.new
|
9
|
-
enum_count =
|
10
|
-
begin
|
11
|
-
size
|
12
|
-
rescue NameError
|
13
|
-
count
|
14
|
-
end
|
15
9
|
|
16
10
|
::Enumerator.new do |yielder|
|
17
11
|
output = []
|
18
|
-
run = 1
|
19
12
|
each do |element, *rest|
|
20
13
|
elements = rest.any? ? [element, *rest] : element
|
21
14
|
|
22
15
|
output.push(elements)
|
23
|
-
if matcher ===
|
16
|
+
if matcher === output.last # rubocop:disable Style/CaseEquality
|
24
17
|
yielder << output
|
25
18
|
output = []
|
26
19
|
end
|
20
|
+
end
|
21
|
+
yielder << output unless output.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def slice_when
|
26
|
+
block = ::Proc.new
|
27
|
+
|
28
|
+
::Enumerator.new do |yielder|
|
29
|
+
output = []
|
30
|
+
each do |element, *rest|
|
31
|
+
elements = rest.any? ? [element, *rest] : element
|
27
32
|
|
28
|
-
|
33
|
+
if output.empty? || !block.call(output.last, elements)
|
34
|
+
output.push(elements)
|
35
|
+
else
|
36
|
+
yielder << output
|
37
|
+
output = [elements]
|
38
|
+
end
|
29
39
|
end
|
40
|
+
yielder << output unless output.empty?
|
30
41
|
end
|
31
42
|
end
|
32
43
|
end
|
@@ -4,35 +4,19 @@ module Polyfill
|
|
4
4
|
def chunk_while
|
5
5
|
block = ::Proc.new
|
6
6
|
|
7
|
-
enum_count =
|
8
|
-
begin
|
9
|
-
size
|
10
|
-
rescue NameError
|
11
|
-
count
|
12
|
-
end
|
13
|
-
|
14
|
-
return [self] if enum_count == 1
|
15
|
-
|
16
7
|
::Enumerator.new do |yielder|
|
17
8
|
output = []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
output.push(a)
|
25
|
-
yielder << output
|
26
|
-
yielder << [b]
|
27
|
-
end
|
9
|
+
each do |element, *rest|
|
10
|
+
elements = rest.any? ? [element, *rest] : element
|
11
|
+
|
12
|
+
if output.empty? || block.call(output.last, elements)
|
13
|
+
output.push(elements)
|
28
14
|
else
|
29
|
-
output
|
30
|
-
|
31
|
-
yielder << output
|
32
|
-
output = []
|
33
|
-
end
|
15
|
+
yielder << output
|
16
|
+
output = [elements]
|
34
17
|
end
|
35
18
|
end
|
19
|
+
yielder << output unless output.empty?
|
36
20
|
end
|
37
21
|
end
|
38
22
|
|
data/lib/polyfill/v2_4/array.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative 'numeric'
|
2
|
+
|
1
3
|
module Polyfill
|
2
4
|
module V2_4
|
3
5
|
module Array
|
6
|
+
using Polyfill(Numeric: %w[#dup])
|
7
|
+
|
4
8
|
def concat(*others)
|
5
9
|
return super if others.length == 1
|
6
10
|
|
@@ -13,14 +17,10 @@ module Polyfill
|
|
13
17
|
end
|
14
18
|
|
15
19
|
def sum(init = 0)
|
16
|
-
acc =
|
17
|
-
begin
|
18
|
-
init.dup
|
19
|
-
rescue TypeError
|
20
|
-
init
|
21
|
-
end
|
20
|
+
acc = init.dup
|
22
21
|
|
23
|
-
|
22
|
+
for i in 0..(size - 1) # rubocop:disable Style/For
|
23
|
+
elem = self[i]
|
24
24
|
acc += block_given? ? yield(elem) : elem
|
25
25
|
end
|
26
26
|
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative 'numeric'
|
2
|
+
|
1
3
|
module Polyfill
|
2
4
|
module V2_4
|
3
5
|
module Enumerable
|
6
|
+
using Polyfill(Numeric: %w[#dup])
|
7
|
+
|
4
8
|
def chunk(*)
|
5
9
|
return enum_for(:chunk) unless block_given?
|
6
10
|
|
@@ -8,12 +12,7 @@ module Polyfill
|
|
8
12
|
end
|
9
13
|
|
10
14
|
def sum(init = 0)
|
11
|
-
acc =
|
12
|
-
begin
|
13
|
-
init.dup
|
14
|
-
rescue TypeError
|
15
|
-
init
|
16
|
-
end
|
15
|
+
acc = init.dup
|
17
16
|
|
18
17
|
each do |elem|
|
19
18
|
acc += block_given? ? yield(elem) : elem
|
data/lib/polyfill/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polyfill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Lasseigne
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|