backports 3.22.1 → 3.24.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +410 -307
- data/README.md +39 -5
- data/lib/backports/2.7.0/symbol/end_with.rb +9 -0
- data/lib/backports/2.7.0/symbol/start_with.rb +9 -0
- data/lib/backports/3.0.0/symbol/name.rb +16 -6
- data/lib/backports/3.1.0/integer/try_convert.rb +7 -0
- data/lib/backports/3.1.0/integer.rb +3 -0
- data/lib/backports/3.2.0/class/attached_object.rb +10 -0
- data/lib/backports/3.2.0/class.rb +3 -0
- data/lib/backports/3.2.0/data.rb +149 -0
- data/lib/backports/3.2.0/enumerator/product.rb +64 -0
- data/lib/backports/3.2.0/enumerator.rb +3 -0
- data/lib/backports/3.2.0/hash/shift.rb +10 -0
- data/lib/backports/3.2.0/hash.rb +3 -0
- data/lib/backports/3.2.0/integer/ceildiv.rb +7 -0
- data/lib/backports/3.2.0/integer.rb +3 -0
- data/lib/backports/3.2.0/match_data/byteoffset.rb +12 -0
- data/lib/backports/3.2.0/match_data.rb +3 -0
- data/lib/backports/3.2.0.rb +3 -0
- data/lib/backports/3.2.rb +1 -0
- data/lib/backports/version.rb +1 -1
- metadata +24 -8
- data/lib/backports/3.1.0/class/descendants.rb +0 -11
- /data/lib/backports/{3.1.0/class.rb → 2.7.0/symbol.rb} +0 -0
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Backports Library [<img src="https://travis-ci.org/marcandre/backports.svg?branch=master">](https://travis-ci.org/marcandre/backports) [<img src="https://badge.fury.io/rb/backports.svg" alt="Gem Version" />](http://badge.fury.io/rb/backports) [](https://tidelift.com/subscription/pkg/rubygems-backports?utm_source=rubygems-backports&utm_medium=referral&utm_campaign=readme)
|
2
2
|
|
3
|
-
Yearning to write a gem using some new cool features in Ruby 3.
|
3
|
+
Yearning to write a gem using some new cool features in Ruby 3.2 while
|
4
4
|
still supporting Ruby 2.5.x?
|
5
5
|
Have some legacy code in Ruby 1.8 but can't live without `flat_map`?
|
6
6
|
|
@@ -38,12 +38,12 @@ This will make sure that Hash responds to `dig`, `fetch_values`, `to_proc` and c
|
|
38
38
|
### Up to a specific Ruby version (for quick coding)
|
39
39
|
|
40
40
|
You can load all backports up to a specific version.
|
41
|
-
For example, to bring any version of Ruby mostly up to Ruby 3.
|
41
|
+
For example, to bring any version of Ruby mostly up to Ruby 3.2.0's standards:
|
42
42
|
|
43
|
-
require 'backports/3.
|
43
|
+
require 'backports/3.2.0'
|
44
44
|
|
45
45
|
This will bring in all the features of 1.8.7 and many features of Ruby 1.9.x
|
46
|
-
all the way up to Ruby 3.
|
46
|
+
all the way up to Ruby 3.2.0 (for all versions of Ruby)!
|
47
47
|
|
48
48
|
You may `require 'backports/latest'` as a
|
49
49
|
shortcut to the latest Ruby version supported.
|
@@ -109,6 +109,32 @@ itself, JRuby and Rubinius.
|
|
109
109
|
|
110
110
|
# Complete List of backports
|
111
111
|
|
112
|
+
## Ruby 3.2 backports
|
113
|
+
|
114
|
+
#### Class
|
115
|
+
|
116
|
+
- `attached_object`
|
117
|
+
|
118
|
+
#### Data
|
119
|
+
|
120
|
+
- Complete class
|
121
|
+
|
122
|
+
#### Enumerator
|
123
|
+
|
124
|
+
- `Enumerator.product` and `Enumerator::Product`
|
125
|
+
|
126
|
+
#### Hash
|
127
|
+
|
128
|
+
- `shift` (with correct behavior when empty)
|
129
|
+
|
130
|
+
#### Integer
|
131
|
+
|
132
|
+
- `ceildiv`
|
133
|
+
|
134
|
+
#### MatchData
|
135
|
+
|
136
|
+
- `byteoffset`
|
137
|
+
|
112
138
|
## Ruby 3.1 backports
|
113
139
|
|
114
140
|
#### Array
|
@@ -117,7 +143,6 @@ itself, JRuby and Rubinius.
|
|
117
143
|
|
118
144
|
#### Class
|
119
145
|
|
120
|
-
- `descendants`
|
121
146
|
- `subclasses`
|
122
147
|
|
123
148
|
#### Enumerable
|
@@ -129,6 +154,10 @@ itself, JRuby and Rubinius.
|
|
129
154
|
|
130
155
|
- `dirname` (with depth argument)
|
131
156
|
|
157
|
+
#### Integer
|
158
|
+
|
159
|
+
- `try_convert`
|
160
|
+
|
132
161
|
#### MatchData
|
133
162
|
|
134
163
|
- `match`
|
@@ -183,6 +212,11 @@ itself, JRuby and Rubinius.
|
|
183
212
|
|
184
213
|
- `produce` (class method)
|
185
214
|
|
215
|
+
#### Symbol
|
216
|
+
|
217
|
+
- `end_with?`
|
218
|
+
- `start_with?`
|
219
|
+
|
186
220
|
#### Time
|
187
221
|
|
188
222
|
- `floor`, `ceil`
|
@@ -1,11 +1,21 @@
|
|
1
1
|
unless Symbol.method_defined? :name
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
if ((ObjectSpace::WeakMap.new[:test] = :test) rescue false)
|
3
|
+
# WeakMaps accept symbols only in Ruby 2.7+
|
4
|
+
def Backports.symbol_names
|
5
|
+
@symbol_names ||= ObjectSpace::WeakMap.new
|
6
|
+
end
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
class Symbol
|
9
|
+
def name
|
10
|
+
Backports.symbol_names[self] ||= to_s.freeze
|
11
|
+
end
|
12
|
+
end
|
13
|
+
else
|
14
|
+
# For earlier Rubies, we can't pool their strings
|
15
|
+
class Symbol
|
16
|
+
def name
|
17
|
+
to_s.freeze
|
18
|
+
end
|
9
19
|
end
|
10
20
|
end
|
11
21
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
unless Class.method_defined? :attached_object
|
2
|
+
require 'backports/2.1.0/module/singleton_class'
|
3
|
+
|
4
|
+
class Class
|
5
|
+
def attached_object
|
6
|
+
raise TypeError, "`#{self}' is not a singleton class" unless singleton_class?
|
7
|
+
ObjectSpace.each_object(self).first
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
original_verbosity = $VERBOSE
|
2
|
+
$VERBOSE = nil
|
3
|
+
if defined?(::Data) && !::Data.respond_to?(:define)
|
4
|
+
Object.send(:remove_const, :Data)
|
5
|
+
end
|
6
|
+
class ::Data
|
7
|
+
end
|
8
|
+
|
9
|
+
module Backports
|
10
|
+
Data = ::Data
|
11
|
+
end
|
12
|
+
$VERBOSE = original_verbosity
|
13
|
+
|
14
|
+
unless ::Backports::Data.respond_to?(:define)
|
15
|
+
require "backports/2.7.0/symbol/end_with"
|
16
|
+
require "backports/2.5.0/module/define_method"
|
17
|
+
|
18
|
+
class ::Backports::Data
|
19
|
+
def deconstruct
|
20
|
+
@__members__.values
|
21
|
+
end
|
22
|
+
|
23
|
+
def deconstruct_keys(keys_or_nil)
|
24
|
+
return @__members__ unless keys_or_nil
|
25
|
+
|
26
|
+
raise TypeError, "Expected symbols" unless keys_or_nil.is_a?(Array) && keys_or_nil.all? {|s| s.is_a?(Symbol)}
|
27
|
+
@__members__.slice(*keys_or_nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.define(*members, &block)
|
31
|
+
members.each do |m|
|
32
|
+
raise TypeError, "#{m} is not a Symbol" unless m.is_a?(Symbol) || m.is_a?(String)
|
33
|
+
raise ArgumentError, "invalid data member: #{m}" if m.end_with?("=")
|
34
|
+
end
|
35
|
+
members = members.map(&:to_sym)
|
36
|
+
raise ArgumentError, "duplicate members" if members.uniq!
|
37
|
+
|
38
|
+
klass = instance_eval <<-"end_define", __FILE__, __LINE__ + 1
|
39
|
+
Class.new(::Backports::Data) do # Class.new(::Data) do
|
40
|
+
def self.members # def self.members
|
41
|
+
#{members.inspect} # [:a_member, :another_member]
|
42
|
+
end # end
|
43
|
+
end # end
|
44
|
+
end_define
|
45
|
+
|
46
|
+
members.each do |m|
|
47
|
+
klass.define_method(m) { @__members__[m]}
|
48
|
+
end
|
49
|
+
|
50
|
+
class << klass
|
51
|
+
def new(*values, **named_values)
|
52
|
+
if named_values.empty?
|
53
|
+
case values.size <=> members.size
|
54
|
+
when -1
|
55
|
+
missing = members[values.size..-1].map(:inspect).join(", ")
|
56
|
+
raise ArgumentError, "Missing keywords: #{missing}"
|
57
|
+
when +1
|
58
|
+
raise ArgumentError, "wrong number of arguments (given #{values.size}, expected 0..#{members.size})"
|
59
|
+
when 0
|
60
|
+
super(**members.zip(values).to_h)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
unless values.empty?
|
64
|
+
raise ArgumentError, "wrong number of arguments (given #{values.size}, expected 0)"
|
65
|
+
end
|
66
|
+
super(**named_values)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
undef :define
|
70
|
+
end
|
71
|
+
|
72
|
+
klass.class_eval(&block) if block
|
73
|
+
|
74
|
+
klass
|
75
|
+
end
|
76
|
+
|
77
|
+
def eql?(other)
|
78
|
+
return false unless other.instance_of?(self.class)
|
79
|
+
|
80
|
+
@__members__.eql?(other.to_h)
|
81
|
+
end
|
82
|
+
|
83
|
+
def ==(other)
|
84
|
+
return false unless other.instance_of?(self.class)
|
85
|
+
|
86
|
+
@__members__ == other.to_h
|
87
|
+
end
|
88
|
+
|
89
|
+
def hash
|
90
|
+
@__members__.hash
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize(**named_values)
|
94
|
+
given = named_values.keys
|
95
|
+
missing = members - given
|
96
|
+
unless missing.empty?
|
97
|
+
missing = missing.map(&:inspect).join(", ")
|
98
|
+
raise ArgumentError, "missing keywords: #{missing}"
|
99
|
+
end
|
100
|
+
if members.size < given.size
|
101
|
+
extra = (given - members).map(&:inspect).join(", ")
|
102
|
+
raise ArgumentError, "unknown keywords: #{extra}"
|
103
|
+
end
|
104
|
+
@__members__ = named_values.freeze
|
105
|
+
freeze
|
106
|
+
end
|
107
|
+
|
108
|
+
# Why is `initialize_copy` specialized in MRI and not just `initialize_dup`?
|
109
|
+
# Let's follow the pattern anyways
|
110
|
+
def initialize_copy(other)
|
111
|
+
@__members__ = other.to_h
|
112
|
+
freeze
|
113
|
+
end
|
114
|
+
|
115
|
+
def inspect
|
116
|
+
data = @__members__.map {|k, v| "#{k}=#{v.inspect}"}.join(", ")
|
117
|
+
space = data != "" && self.class.name ? " " : ""
|
118
|
+
"#<data #{self.class.name}#{space}#{data}>"
|
119
|
+
end
|
120
|
+
|
121
|
+
def marshal_dump
|
122
|
+
@__members__
|
123
|
+
end
|
124
|
+
|
125
|
+
def marshal_load(members)
|
126
|
+
@__members__ = members
|
127
|
+
freeze
|
128
|
+
end
|
129
|
+
|
130
|
+
# class method defined in `define`
|
131
|
+
def members
|
132
|
+
self.class.members
|
133
|
+
end
|
134
|
+
|
135
|
+
class << self
|
136
|
+
private :new
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_h(&block)
|
140
|
+
@__members__.to_h(&block)
|
141
|
+
end
|
142
|
+
|
143
|
+
def with(**update)
|
144
|
+
return self if update.empty?
|
145
|
+
|
146
|
+
self.class.new(**@__members__.merge(update))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
unless Enumerator.method_defined? :product
|
2
|
+
if RUBY_VERSION >= '2.7'
|
3
|
+
instance_eval <<-EOT, __FILE__, __LINE__ + 1
|
4
|
+
def Enumerator.product(*enums, **nil, &block)
|
5
|
+
Enumerator::Product.new(*enums).each(&block)
|
6
|
+
end
|
7
|
+
EOT
|
8
|
+
else
|
9
|
+
def Enumerator.product(*enums, &block)
|
10
|
+
Enumerator::Product.new(*enums).each(&block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Enumerator::Product < Enumerator
|
15
|
+
if RUBY_VERSION >= '2.7'
|
16
|
+
module_eval <<-EOT, __FILE__, __LINE__ + 1
|
17
|
+
def initialize(*enums, **nil)
|
18
|
+
@__enums = enums
|
19
|
+
end
|
20
|
+
EOT
|
21
|
+
else
|
22
|
+
# rubocop:disable Lint/MissingSuper
|
23
|
+
def initialize(*enums)
|
24
|
+
@__enums = enums
|
25
|
+
end
|
26
|
+
# rubocop:enable Lint/MissingSuper
|
27
|
+
end
|
28
|
+
|
29
|
+
def each(&block)
|
30
|
+
return self unless block
|
31
|
+
__execute(block, [], @__enums)
|
32
|
+
end
|
33
|
+
|
34
|
+
def __execute(block, values, enums)
|
35
|
+
if enums.empty?
|
36
|
+
block.yield values
|
37
|
+
else
|
38
|
+
enum, *enums = enums
|
39
|
+
enum.each do |val|
|
40
|
+
__execute(block, [*values, val], enums)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
private :__execute
|
46
|
+
|
47
|
+
def size
|
48
|
+
total_size = 1
|
49
|
+
@__enums.each do |enum|
|
50
|
+
size = enum.size
|
51
|
+
return size if size == nil || size == Float::INFINITY
|
52
|
+
total_size *= size
|
53
|
+
end
|
54
|
+
total_size
|
55
|
+
end
|
56
|
+
|
57
|
+
def rewind
|
58
|
+
@__enums.reverse_each do |enum|
|
59
|
+
enum.rewind if enum.respond_to?(:rewind)
|
60
|
+
end
|
61
|
+
self
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
if Hash.new(42).shift
|
2
|
+
require 'backports/tools/alias_method_chain'
|
3
|
+
|
4
|
+
class Hash
|
5
|
+
def shift_with_correct_behaviour_when_empty
|
6
|
+
shift_without_correct_behaviour_when_empty unless empty?
|
7
|
+
end
|
8
|
+
Backports.alias_method_chain self, :shift, :correct_behaviour_when_empty
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
unless MatchData.method_defined? :byteoffset
|
2
|
+
class MatchData
|
3
|
+
def byteoffset(n)
|
4
|
+
if (char_start_offset = self.begin(n))
|
5
|
+
char_end_offset = self.end(n)
|
6
|
+
[string[0, char_start_offset].bytesize, string[0, char_end_offset].bytesize]
|
7
|
+
else
|
8
|
+
[nil, nil]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'backports/3.2.0'
|
data/lib/backports/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Backports
|
2
|
-
VERSION = "3.
|
2
|
+
VERSION = "3.24.0" unless Backports.constants.include? :VERSION # the guard is against a redefinition warning that happens on Travis
|
3
3
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backports
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-André Lafortune
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Essential backports that enable many of the nice features of Ruby for
|
14
14
|
earlier versions.
|
@@ -531,6 +531,9 @@ files:
|
|
531
531
|
- lib/backports/2.7.0/enumerable/tally.rb
|
532
532
|
- lib/backports/2.7.0/enumerator.rb
|
533
533
|
- lib/backports/2.7.0/enumerator/produce.rb
|
534
|
+
- lib/backports/2.7.0/symbol.rb
|
535
|
+
- lib/backports/2.7.0/symbol/end_with.rb
|
536
|
+
- lib/backports/2.7.0/symbol/start_with.rb
|
534
537
|
- lib/backports/2.7.0/time/ceil.rb
|
535
538
|
- lib/backports/2.7.0/time/floor.rb
|
536
539
|
- lib/backports/2.7.rb
|
@@ -547,20 +550,33 @@ files:
|
|
547
550
|
- lib/backports/3.1.0.rb
|
548
551
|
- lib/backports/3.1.0/array.rb
|
549
552
|
- lib/backports/3.1.0/array/intersect.rb
|
550
|
-
- lib/backports/3.1.0/class.rb
|
551
|
-
- lib/backports/3.1.0/class/descendants.rb
|
552
553
|
- lib/backports/3.1.0/class/subclasses.rb
|
553
554
|
- lib/backports/3.1.0/enumerable.rb
|
554
555
|
- lib/backports/3.1.0/enumerable/compact.rb
|
555
556
|
- lib/backports/3.1.0/enumerable/tally.rb
|
556
557
|
- lib/backports/3.1.0/file.rb
|
557
558
|
- lib/backports/3.1.0/file/dirname.rb
|
559
|
+
- lib/backports/3.1.0/integer.rb
|
560
|
+
- lib/backports/3.1.0/integer/try_convert.rb
|
558
561
|
- lib/backports/3.1.0/match_data.rb
|
559
562
|
- lib/backports/3.1.0/match_data/match.rb
|
560
563
|
- lib/backports/3.1.0/match_data/match_length.rb
|
561
564
|
- lib/backports/3.1.0/struct.rb
|
562
565
|
- lib/backports/3.1.0/struct/keyword_init.rb
|
563
566
|
- lib/backports/3.1.rb
|
567
|
+
- lib/backports/3.2.0.rb
|
568
|
+
- lib/backports/3.2.0/class.rb
|
569
|
+
- lib/backports/3.2.0/class/attached_object.rb
|
570
|
+
- lib/backports/3.2.0/data.rb
|
571
|
+
- lib/backports/3.2.0/enumerator.rb
|
572
|
+
- lib/backports/3.2.0/enumerator/product.rb
|
573
|
+
- lib/backports/3.2.0/hash.rb
|
574
|
+
- lib/backports/3.2.0/hash/shift.rb
|
575
|
+
- lib/backports/3.2.0/integer.rb
|
576
|
+
- lib/backports/3.2.0/integer/ceildiv.rb
|
577
|
+
- lib/backports/3.2.0/match_data.rb
|
578
|
+
- lib/backports/3.2.0/match_data/byteoffset.rb
|
579
|
+
- lib/backports/3.2.rb
|
564
580
|
- lib/backports/basic_object.rb
|
565
581
|
- lib/backports/force/array_map.rb
|
566
582
|
- lib/backports/force/enumerable_map.rb
|
@@ -608,7 +624,7 @@ metadata:
|
|
608
624
|
changelog_uri: https://github.com/marcandre/backports/blob/master/CHANGELOG.md
|
609
625
|
source_code_uri: https://github.com/marcandre/backports
|
610
626
|
bug_tracker_uri: https://github.com/marcandre/backports/issues
|
611
|
-
post_install_message:
|
627
|
+
post_install_message:
|
612
628
|
rdoc_options: []
|
613
629
|
require_paths:
|
614
630
|
- lib
|
@@ -623,8 +639,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
623
639
|
- !ruby/object:Gem::Version
|
624
640
|
version: '0'
|
625
641
|
requirements: []
|
626
|
-
rubygems_version: 3.1.
|
627
|
-
signing_key:
|
642
|
+
rubygems_version: 3.1.6
|
643
|
+
signing_key:
|
628
644
|
specification_version: 4
|
629
645
|
summary: Backports of Ruby features for older Ruby.
|
630
646
|
test_files: []
|
File without changes
|