backports 3.23.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ebf913e1cb86c25292dbf4106e69878788804f7d1e150ba7a41ea2743b4cce7
4
- data.tar.gz: 5caf5e6bc8a92fd2ceff9eed115bdd504b3cac17478b56e798816744c17b5fab
3
+ metadata.gz: 8beaceec7c1ff3819b478521aa32a3777d2ea56a514ba9cb1431c5f89b27dd72
4
+ data.tar.gz: 228023f65abde2103588059a8b5ab2d882bc3616a9033fa3f3398cecabd4cc5d
5
5
  SHA512:
6
- metadata.gz: aac88ca171d07ddcb74fd4fa71cbca9fe82f69f1d8c763ccaa54cd8b2328bae08af481f0011937f98fb2c79ee4484e17ac1d606d42f0a424d5677b91f50935f6
7
- data.tar.gz: a7a179a5c9e51e767180d822b7dd2976312a44221f7f2e33a00f682e9f28e747fa7d00c4d81541af9011bb4aba4b12025b6f7e6f2c4050a94608897995ee8248
6
+ metadata.gz: ea8d7a6e510d0da24ca48a43436956c231800e651f55d439e6568f0859fb33366879df4179f41fab8a343f636c9c90784161931feb70d70a59d1ac4e937f8d59
7
+ data.tar.gz: 684267e5d459a983d616e5a6ed67fbe29fc4df0ed0b6c46610a07d4b5b5953d015f122aff10b91dc055cef72ef013458c2f66a9ff14ee39da22b3c8941d44279
data/CHANGELOG.md CHANGED
@@ -4,9 +4,21 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [Unreleased]
7
+ ## [3.24.0](https://github.com/marcandre/backports/compare/v3.23.0...v3.24.0) - 2023-03-07
8
8
 
9
- Note: [Next major version (X-mas 2021?)](https://github.com/marcandre/backports/issues/139) may drop support for Ruby < 2.2, please comment.
9
+ ## Added
10
+
11
+ - `Class#attached_object` (Ruby 3.2)
12
+ - `Data` (Ruby 3.2)
13
+ - `Enumerator.product` and `Enumerator::Product` (Ruby 3.2)
14
+ - `Hash#shift` (with correct behavior when empty) (Ruby 3.2)
15
+ - `Integer#ceildiv` (Ruby 3.2)
16
+ - `MatchData#byteoffset` (Ruby 3.2)
17
+ - `Symbol#start_with?` (Ruby 2.7)
18
+
19
+ ## Fixed
20
+
21
+ - `Class#descendants` (removed, as it was not actually added in Ruby 3.1, sorry)
10
22
 
11
23
  ## [3.23.0](https://github.com/marcandre/backports/compare/v3.22.1...v3.23.0) - 2021-12-28
12
24
 
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) [![Tidelift](https://tidelift.com/badges/package/rubygems/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.1 while
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.1.0's standards:
41
+ For example, to bring any version of Ruby mostly up to Ruby 3.2.0's standards:
42
42
 
43
- require 'backports/3.1.0'
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.1.0 (for all versions of Ruby)!
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
@@ -188,7 +213,9 @@ itself, JRuby and Rubinius.
188
213
  - `produce` (class method)
189
214
 
190
215
  #### Symbol
191
- - `end_with?`
216
+
217
+ - `end_with?`
218
+ - `start_with?`
192
219
 
193
220
  #### Time
194
221
 
@@ -0,0 +1,9 @@
1
+ require 'backports/1.8.7/string/start_with' unless String.method_defined? :end_with?
2
+
3
+ unless Symbol.method_defined?(:start_with?)
4
+ class Symbol
5
+ def start_with?(*suffixes)
6
+ to_s.start_with?(*suffixes)
7
+ end
8
+ end
9
+ 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,3 @@
1
+ require 'backports/tools/require_relative_dir'
2
+
3
+ Backports.require_relative_dir
@@ -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,3 @@
1
+ require 'backports/tools/require_relative_dir'
2
+
3
+ Backports.require_relative_dir
@@ -0,0 +1,7 @@
1
+ unless Integer.method_defined? :ceildiv
2
+ class Integer
3
+ def ceildiv(arg)
4
+ fdiv(arg).ceil
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ require 'backports/tools/require_relative_dir'
2
+
3
+ Backports.require_relative_dir
@@ -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,3 @@
1
+ require 'backports/tools/require_relative_dir'
2
+
3
+ Backports.require_relative_dir
@@ -0,0 +1,3 @@
1
+ # require this file to load all the backports up to Ruby 3.0
2
+ require 'backports/3.1.0'
3
+ Backports.require_relative_dir if RUBY_VERSION < '3.2'
@@ -0,0 +1 @@
1
+ require 'backports/3.2.0'
@@ -1,3 +1,3 @@
1
1
  module Backports
2
- VERSION = "3.23.0" unless Backports.constants.include? :VERSION # the guard is against a redefinition warning that happens on Travis
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.23.0
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: 2021-12-28 00:00:00.000000000 Z
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.
@@ -533,6 +533,7 @@ files:
533
533
  - lib/backports/2.7.0/enumerator/produce.rb
534
534
  - lib/backports/2.7.0/symbol.rb
535
535
  - lib/backports/2.7.0/symbol/end_with.rb
536
+ - lib/backports/2.7.0/symbol/start_with.rb
536
537
  - lib/backports/2.7.0/time/ceil.rb
537
538
  - lib/backports/2.7.0/time/floor.rb
538
539
  - lib/backports/2.7.rb
@@ -549,8 +550,6 @@ files:
549
550
  - lib/backports/3.1.0.rb
550
551
  - lib/backports/3.1.0/array.rb
551
552
  - lib/backports/3.1.0/array/intersect.rb
552
- - lib/backports/3.1.0/class.rb
553
- - lib/backports/3.1.0/class/descendants.rb
554
553
  - lib/backports/3.1.0/class/subclasses.rb
555
554
  - lib/backports/3.1.0/enumerable.rb
556
555
  - lib/backports/3.1.0/enumerable/compact.rb
@@ -565,6 +564,19 @@ files:
565
564
  - lib/backports/3.1.0/struct.rb
566
565
  - lib/backports/3.1.0/struct/keyword_init.rb
567
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
568
580
  - lib/backports/basic_object.rb
569
581
  - lib/backports/force/array_map.rb
570
582
  - lib/backports/force/enumerable_map.rb
@@ -612,7 +624,7 @@ metadata:
612
624
  changelog_uri: https://github.com/marcandre/backports/blob/master/CHANGELOG.md
613
625
  source_code_uri: https://github.com/marcandre/backports
614
626
  bug_tracker_uri: https://github.com/marcandre/backports/issues
615
- post_install_message:
627
+ post_install_message:
616
628
  rdoc_options: []
617
629
  require_paths:
618
630
  - lib
@@ -627,8 +639,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
627
639
  - !ruby/object:Gem::Version
628
640
  version: '0'
629
641
  requirements: []
630
- rubygems_version: 3.3.3
631
- signing_key:
642
+ rubygems_version: 3.1.6
643
+ signing_key:
632
644
  specification_version: 4
633
645
  summary: Backports of Ruby features for older Ruby.
634
646
  test_files: []
@@ -1,11 +0,0 @@
1
- unless Class.method_defined? :descendants
2
- require 'backports/2.1.0/module/singleton_class'
3
-
4
- class Class
5
- def descendants
6
- ObjectSpace.each_object(singleton_class).reject do |klass|
7
- klass.singleton_class? || klass == self
8
- end
9
- end
10
- end
11
- end
File without changes