activesupport 8.0.0 → 8.1.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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +391 -67
  3. data/README.rdoc +1 -1
  4. data/lib/active_support/backtrace_cleaner.rb +72 -1
  5. data/lib/active_support/broadcast_logger.rb +61 -74
  6. data/lib/active_support/cache/file_store.rb +2 -2
  7. data/lib/active_support/cache/mem_cache_store.rb +26 -28
  8. data/lib/active_support/cache/memory_store.rb +5 -5
  9. data/lib/active_support/cache/null_store.rb +2 -2
  10. data/lib/active_support/cache/redis_cache_store.rb +37 -31
  11. data/lib/active_support/cache/strategy/local_cache.rb +72 -27
  12. data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
  13. data/lib/active_support/cache.rb +72 -9
  14. data/lib/active_support/callbacks.rb +27 -11
  15. data/lib/active_support/class_attribute.rb +15 -8
  16. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
  17. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  18. data/lib/active_support/configurable.rb +34 -0
  19. data/lib/active_support/continuous_integration.rb +145 -0
  20. data/lib/active_support/core_ext/array/conversions.rb +3 -3
  21. data/lib/active_support/core_ext/array.rb +7 -7
  22. data/lib/active_support/core_ext/benchmark.rb +4 -11
  23. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  24. data/lib/active_support/core_ext/class/attribute.rb +20 -5
  25. data/lib/active_support/core_ext/class.rb +2 -2
  26. data/lib/active_support/core_ext/date.rb +5 -5
  27. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
  28. data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
  29. data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
  30. data/lib/active_support/core_ext/date_time.rb +5 -5
  31. data/lib/active_support/core_ext/digest.rb +1 -1
  32. data/lib/active_support/core_ext/enumerable.rb +17 -5
  33. data/lib/active_support/core_ext/erb/util.rb +5 -5
  34. data/lib/active_support/core_ext/file.rb +1 -1
  35. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -0
  36. data/lib/active_support/core_ext/hash.rb +8 -8
  37. data/lib/active_support/core_ext/integer.rb +3 -3
  38. data/lib/active_support/core_ext/kernel.rb +3 -3
  39. data/lib/active_support/core_ext/module/introspection.rb +3 -0
  40. data/lib/active_support/core_ext/module.rb +11 -11
  41. data/lib/active_support/core_ext/numeric.rb +3 -3
  42. data/lib/active_support/core_ext/object/json.rb +8 -1
  43. data/lib/active_support/core_ext/object/to_query.rb +7 -1
  44. data/lib/active_support/core_ext/object/try.rb +2 -2
  45. data/lib/active_support/core_ext/object.rb +13 -13
  46. data/lib/active_support/core_ext/pathname.rb +2 -2
  47. data/lib/active_support/core_ext/range/overlap.rb +3 -3
  48. data/lib/active_support/core_ext/range/sole.rb +17 -0
  49. data/lib/active_support/core_ext/range.rb +4 -4
  50. data/lib/active_support/core_ext/securerandom.rb +24 -8
  51. data/lib/active_support/core_ext/string/filters.rb +3 -3
  52. data/lib/active_support/core_ext/string/multibyte.rb +12 -3
  53. data/lib/active_support/core_ext/string/output_safety.rb +19 -12
  54. data/lib/active_support/core_ext/string.rb +13 -13
  55. data/lib/active_support/core_ext/symbol.rb +1 -1
  56. data/lib/active_support/core_ext/time/calculations.rb +0 -7
  57. data/lib/active_support/core_ext/time/compatibility.rb +2 -27
  58. data/lib/active_support/core_ext/time.rb +5 -5
  59. data/lib/active_support/core_ext.rb +1 -1
  60. data/lib/active_support/current_attributes/test_helper.rb +2 -2
  61. data/lib/active_support/current_attributes.rb +27 -17
  62. data/lib/active_support/dependencies/interlock.rb +11 -5
  63. data/lib/active_support/dependencies.rb +6 -1
  64. data/lib/active_support/deprecation/reporting.rb +4 -2
  65. data/lib/active_support/deprecation.rb +1 -1
  66. data/lib/active_support/editor.rb +70 -0
  67. data/lib/active_support/error_reporter.rb +61 -8
  68. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  69. data/lib/active_support/event_reporter.rb +592 -0
  70. data/lib/active_support/evented_file_update_checker.rb +5 -1
  71. data/lib/active_support/execution_context.rb +64 -7
  72. data/lib/active_support/execution_wrapper.rb +1 -1
  73. data/lib/active_support/file_update_checker.rb +8 -6
  74. data/lib/active_support/gem_version.rb +1 -1
  75. data/lib/active_support/gzip.rb +1 -0
  76. data/lib/active_support/hash_with_indifferent_access.rb +47 -24
  77. data/lib/active_support/i18n_railtie.rb +1 -2
  78. data/lib/active_support/inflector/inflections.rb +31 -15
  79. data/lib/active_support/inflector/transliterate.rb +6 -8
  80. data/lib/active_support/isolated_execution_state.rb +12 -15
  81. data/lib/active_support/json/decoding.rb +6 -4
  82. data/lib/active_support/json/encoding.rb +155 -19
  83. data/lib/active_support/lazy_load_hooks.rb +1 -1
  84. data/lib/active_support/log_subscriber.rb +2 -6
  85. data/lib/active_support/logger_thread_safe_level.rb +6 -3
  86. data/lib/active_support/message_encryptors.rb +54 -2
  87. data/lib/active_support/message_pack/extensions.rb +5 -0
  88. data/lib/active_support/message_verifier.rb +9 -0
  89. data/lib/active_support/message_verifiers.rb +57 -3
  90. data/lib/active_support/messages/rotation_coordinator.rb +9 -0
  91. data/lib/active_support/messages/rotator.rb +10 -0
  92. data/lib/active_support/multibyte/chars.rb +12 -2
  93. data/lib/active_support/multibyte.rb +4 -0
  94. data/lib/active_support/notifications/fanout.rb +64 -42
  95. data/lib/active_support/notifications/instrumenter.rb +1 -1
  96. data/lib/active_support/railtie.rb +32 -13
  97. data/lib/active_support/structured_event_subscriber.rb +99 -0
  98. data/lib/active_support/subscriber.rb +0 -5
  99. data/lib/active_support/syntax_error_proxy.rb +3 -0
  100. data/lib/active_support/test_case.rb +61 -6
  101. data/lib/active_support/testing/assertions.rb +34 -6
  102. data/lib/active_support/testing/error_reporter_assertions.rb +18 -1
  103. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  104. data/lib/active_support/testing/notification_assertions.rb +92 -0
  105. data/lib/active_support/testing/parallelization/server.rb +15 -2
  106. data/lib/active_support/testing/parallelization/worker.rb +4 -2
  107. data/lib/active_support/testing/parallelization.rb +25 -1
  108. data/lib/active_support/testing/tests_without_assertions.rb +1 -1
  109. data/lib/active_support/testing/time_helpers.rb +7 -3
  110. data/lib/active_support/time_with_zone.rb +23 -23
  111. data/lib/active_support/values/time_zone.rb +8 -1
  112. data/lib/active_support/xml_mini.rb +3 -2
  113. data/lib/active_support.rb +20 -15
  114. metadata +27 -23
  115. data/lib/active_support/core_ext/range/each.rb +0 -24
  116. data/lib/active_support/testing/strict_warnings.rb +0 -43
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/array/wrap"
4
- require "active_support/core_ext/array/access"
5
- require "active_support/core_ext/array/conversions"
6
- require "active_support/core_ext/array/extract"
7
- require "active_support/core_ext/array/extract_options"
8
- require "active_support/core_ext/array/grouping"
9
- require "active_support/core_ext/array/inquiry"
3
+ require_relative "array/wrap"
4
+ require_relative "array/access"
5
+ require_relative "array/conversions"
6
+ require_relative "array/extract"
7
+ require_relative "array/extract_options"
8
+ require_relative "array/grouping"
9
+ require_relative "array/inquiry"
@@ -1,13 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "benchmark"
4
-
5
- class << Benchmark
6
- def ms(&block) # :nodoc
7
- # NOTE: Please also remove the Active Support `benchmark` dependency when removing this
8
- ActiveSupport.deprecator.warn <<~TEXT
9
- `Benchmark.ms` is deprecated and will be removed in Rails 8.1 without replacement.
10
- TEXT
11
- ActiveSupport::Benchmark.realtime(:float_millisecond, &block)
12
- end
13
- end
3
+ # Remove this file from activesupport/lib/active_support/core_ext.rb when deleting the deprecation.
4
+ ActiveSupport.deprecator.warn <<~TEXT
5
+ active_support/core_ext/benchmark.rb is deprecated and will be removed in Rails 8.2 without replacement.
6
+ TEXT
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/big_decimal/conversions"
3
+ require_relative "big_decimal/conversions"
@@ -84,8 +84,8 @@ class Class
84
84
  #
85
85
  # class_attribute :settings, default: {}
86
86
  def class_attribute(*attrs, instance_accessor: true,
87
- instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
88
-
87
+ instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil
88
+ )
89
89
  class_methods, methods = [], []
90
90
  attrs.each do |name|
91
91
  unless name.is_a?(Symbol) || name.is_a?(String)
@@ -93,12 +93,27 @@ class Class
93
93
  end
94
94
 
95
95
  name = name.to_sym
96
- ::ActiveSupport::ClassAttribute.redefine(self, name, default)
96
+ namespaced_name = :"__class_attr_#{name}"
97
+ ::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, default)
98
+
99
+ class_methods << "def #{name}; #{namespaced_name}; end"
100
+ class_methods << "def #{name}=(value); self.#{namespaced_name} = value; end"
97
101
 
98
- unless singleton_class?
102
+ if singleton_class?
103
+ methods << <<~RUBY if instance_reader
104
+ silence_redefinition_of_method(:#{name})
105
+ def #{name}
106
+ self.singleton_class.#{name}
107
+ end
108
+ RUBY
109
+ else
99
110
  methods << <<~RUBY if instance_reader
100
111
  silence_redefinition_of_method def #{name}
101
- defined?(@#{name}) ? @#{name} : self.class.#{name}
112
+ if defined?(@#{name})
113
+ @#{name}
114
+ else
115
+ self.class.#{name}
116
+ end
102
117
  end
103
118
  RUBY
104
119
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/class/attribute"
4
- require "active_support/core_ext/class/subclasses"
3
+ require_relative "class/attribute"
4
+ require_relative "class/subclasses"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/date/acts_like"
4
- require "active_support/core_ext/date/blank"
5
- require "active_support/core_ext/date/calculations"
6
- require "active_support/core_ext/date/conversions"
7
- require "active_support/core_ext/date/zones"
3
+ require_relative "date/acts_like"
4
+ require_relative "date/blank"
5
+ require_relative "date/calculations"
6
+ require_relative "date/conversions"
7
+ require_relative "date/zones"
@@ -5,41 +5,6 @@ require "active_support/core_ext/module/redefine_method"
5
5
 
6
6
  module DateAndTime
7
7
  module Compatibility
8
- # If true, +to_time+ preserves the timezone offset of receiver.
9
- #
10
- # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
11
- # converting to the local system time, to preserving the offset
12
- # of the receiver. For backwards compatibility we're overriding
13
- # this behavior, but new apps will have an initializer that sets
14
- # this to true, because the new behavior is preferred.
15
- mattr_accessor :preserve_timezone, instance_accessor: false, default: nil
16
-
17
- singleton_class.silence_redefinition_of_method :preserve_timezone
18
-
19
- #--
20
- # This re-implements the behaviour of the mattr_reader, instead
21
- # of prepending on to it, to avoid overcomplicating a module that
22
- # is in turn included in several places. This will all go away in
23
- # Rails 8.0 anyway.
24
- def self.preserve_timezone # :nodoc:
25
- if @@preserve_timezone.nil?
26
- # Only warn once, the first time the value is used (which should
27
- # be the first time #to_time is called).
28
- ActiveSupport.deprecator.warn(
29
- "`to_time` will always preserve the receiver timezone rather than system local time in Rails 8.1." \
30
- "To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`."
31
- )
32
-
33
- @@preserve_timezone = false
34
- end
35
-
36
- @@preserve_timezone
37
- end
38
-
39
- def preserve_timezone # :nodoc:
40
- Compatibility.preserve_timezone
41
- end
42
-
43
8
  # Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
44
9
  #
45
10
  # When +true+, it returns local times with a UTC offset, with +false+ local
@@ -8,11 +8,9 @@ class DateTime
8
8
 
9
9
  silence_redefinition_of_method :to_time
10
10
 
11
- # Either return an instance of +Time+ with the same UTC offset
12
- # as +self+ or an instance of +Time+ representing the same time
13
- # in the local system timezone depending on the setting of
14
- # on the setting of +ActiveSupport.to_time_preserves_timezone+.
11
+ # Return an instance of +Time+ with the same UTC offset
12
+ # as +self+.
15
13
  def to_time
16
- preserve_timezone ? getlocal(utc_offset) : getlocal
14
+ getlocal(utc_offset)
17
15
  end
18
16
  end
@@ -11,7 +11,8 @@ class DateTime
11
11
  #
12
12
  # This method is aliased to <tt>to_formatted_s</tt>.
13
13
  #
14
- # === Examples
14
+ # ==== Examples
15
+ #
15
16
  # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
16
17
  #
17
18
  # datetime.to_fs(:db) # => "2007-12-04 00:00:00"
@@ -23,7 +24,8 @@ class DateTime
23
24
  # datetime.to_fs(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
24
25
  # datetime.to_fs(:iso8601) # => "2007-12-04T00:00:00+00:00"
25
26
  #
26
- # == Adding your own datetime formats to to_fs
27
+ # ==== Adding your own datetime formats to +to_fs+
28
+ #
27
29
  # DateTime formats are shared with Time. You can add your own to the
28
30
  # Time::DATE_FORMATS hash. Use the format name as the hash key and
29
31
  # either a strftime string or Proc instance that takes a time or
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/date_time/acts_like"
4
- require "active_support/core_ext/date_time/blank"
5
- require "active_support/core_ext/date_time/calculations"
6
- require "active_support/core_ext/date_time/compatibility"
7
- require "active_support/core_ext/date_time/conversions"
3
+ require_relative "date_time/acts_like"
4
+ require_relative "date_time/blank"
5
+ require_relative "date_time/calculations"
6
+ require_relative "date_time/compatibility"
7
+ require_relative "date_time/conversions"
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/digest/uuid"
3
+ require_relative "digest/uuid"
@@ -203,16 +203,28 @@ module Enumerable
203
203
  end
204
204
 
205
205
  # Returns the sole item in the enumerable. If there are no items, or more
206
- # than one item, raises +Enumerable::SoleItemExpectedError+.
206
+ # than one item, raises Enumerable::SoleItemExpectedError.
207
207
  #
208
208
  # ["x"].sole # => "x"
209
209
  # Set.new.sole # => Enumerable::SoleItemExpectedError: no item found
210
210
  # { a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
211
211
  def sole
212
- case count
213
- when 1 then return first # rubocop:disable Style/RedundantReturn
214
- when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
215
- when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
212
+ result = nil
213
+ found = false
214
+
215
+ each do |*element|
216
+ if found
217
+ raise SoleItemExpectedError, "multiple items found"
218
+ end
219
+
220
+ result = element.size == 1 ? element[0] : element
221
+ found = true
222
+ end
223
+
224
+ if found
225
+ result
226
+ else
227
+ raise SoleItemExpectedError, "no item found"
216
228
  end
217
229
  end
218
230
  end
@@ -12,7 +12,7 @@ module ActiveSupport
12
12
  if s.html_safe?
13
13
  s
14
14
  else
15
- super(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
15
+ super(s)
16
16
  end
17
17
  end
18
18
  alias :unwrapped_html_escape :html_escape # :nodoc:
@@ -61,7 +61,7 @@ class ERB
61
61
  # html_escape_once('&lt;&lt; Accept & Checkout')
62
62
  # # => "&lt;&lt; Accept &amp; Checkout"
63
63
  def html_escape_once(s)
64
- ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe
64
+ s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe
65
65
  end
66
66
 
67
67
  module_function :html_escape_once
@@ -169,12 +169,12 @@ class ERB
169
169
  while !source.eos?
170
170
  pos = source.pos
171
171
  source.scan_until(/(?:#{start_re}|#{finish_re})/)
172
- raise NotImplementedError if source.matched.nil?
172
+ return [[:PLAIN, source.string]] unless source.matched?
173
173
  len = source.pos - source.matched.bytesize - pos
174
174
 
175
175
  case source.matched
176
176
  when start_re
177
- tokens << [:TEXT, source.string[pos, len]] if len > 0
177
+ tokens << [:TEXT, source.string.byteslice(pos, len)] if len > 0
178
178
  tokens << [:OPEN, source.matched]
179
179
  if source.scan(/(.*?)(?=#{finish_re}|\z)/m)
180
180
  tokens << [:CODE, source.matched] unless source.matched.empty?
@@ -183,7 +183,7 @@ class ERB
183
183
  raise NotImplementedError
184
184
  end
185
185
  when finish_re
186
- tokens << [:CODE, source.string[pos, len]] if len > 0
186
+ tokens << [:CODE, source.string.byteslice(pos, len)] if len > 0
187
187
  tokens << [:CLOSE, source.matched]
188
188
  else
189
189
  raise NotImplementedError, source.matched
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/file/atomic"
3
+ require_relative "file/atomic"
@@ -36,6 +36,7 @@ class Hash
36
36
  #--
37
37
  # Implemented by ActiveSupport::DeepMergeable#deep_merge!.
38
38
 
39
+ ##
39
40
  def deep_merge?(other) # :nodoc:
40
41
  other.is_a?(Hash)
41
42
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/hash/conversions"
4
- require "active_support/core_ext/hash/deep_merge"
5
- require "active_support/core_ext/hash/deep_transform_values"
6
- require "active_support/core_ext/hash/except"
7
- require "active_support/core_ext/hash/indifferent_access"
8
- require "active_support/core_ext/hash/keys"
9
- require "active_support/core_ext/hash/reverse_merge"
10
- require "active_support/core_ext/hash/slice"
3
+ require_relative "hash/conversions"
4
+ require_relative "hash/deep_merge"
5
+ require_relative "hash/deep_transform_values"
6
+ require_relative "hash/except"
7
+ require_relative "hash/indifferent_access"
8
+ require_relative "hash/keys"
9
+ require_relative "hash/reverse_merge"
10
+ require_relative "hash/slice"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/integer/multiple"
4
- require "active_support/core_ext/integer/inflections"
5
- require "active_support/core_ext/integer/time"
3
+ require_relative "integer/multiple"
4
+ require_relative "integer/inflections"
5
+ require_relative "integer/time"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/kernel/concern"
4
- require "active_support/core_ext/kernel/reporting"
5
- require "active_support/core_ext/kernel/singleton_class"
3
+ require_relative "kernel/concern"
4
+ require_relative "kernel/reporting"
5
+ require_relative "kernel/singleton_class"
@@ -10,6 +10,9 @@ class Module
10
10
  if defined?(@parent_name)
11
11
  @parent_name
12
12
  else
13
+ name = self.name
14
+ return if name.nil?
15
+
13
16
  parent_name = name =~ /::[^:]+\z/ ? -$` : nil
14
17
  @parent_name = parent_name unless frozen?
15
18
  parent_name
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/module/aliasing"
4
- require "active_support/core_ext/module/introspection"
5
- require "active_support/core_ext/module/anonymous"
6
- require "active_support/core_ext/module/attribute_accessors"
7
- require "active_support/core_ext/module/attribute_accessors_per_thread"
8
- require "active_support/core_ext/module/attr_internal"
9
- require "active_support/core_ext/module/concerning"
10
- require "active_support/core_ext/module/delegation"
11
- require "active_support/core_ext/module/deprecation"
12
- require "active_support/core_ext/module/redefine_method"
13
- require "active_support/core_ext/module/remove_method"
3
+ require_relative "module/aliasing"
4
+ require_relative "module/introspection"
5
+ require_relative "module/anonymous"
6
+ require_relative "module/attribute_accessors"
7
+ require_relative "module/attribute_accessors_per_thread"
8
+ require_relative "module/attr_internal"
9
+ require_relative "module/concerning"
10
+ require_relative "module/delegation"
11
+ require_relative "module/deprecation"
12
+ require_relative "module/redefine_method"
13
+ require_relative "module/remove_method"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/numeric/bytes"
4
- require "active_support/core_ext/numeric/time"
5
- require "active_support/core_ext/numeric/conversions"
3
+ require_relative "numeric/bytes"
4
+ require_relative "numeric/time"
5
+ require_relative "numeric/conversions"
@@ -240,9 +240,16 @@ class Pathname # :nodoc:
240
240
  end
241
241
 
242
242
  unless IPAddr.method_defined?(:as_json, false)
243
+ # Use `IPAddr#as_json` from the IPAddr gem if the version is 1.2.7 or higher.
243
244
  class IPAddr # :nodoc:
244
245
  def as_json(options = nil)
245
- to_s
246
+ if ipv4? && prefix == 32
247
+ to_s
248
+ elsif ipv6? && prefix == 128
249
+ to_s
250
+ else
251
+ "#{self}/#{prefix}"
252
+ end
246
253
  end
247
254
  end
248
255
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cgi"
3
+ require "cgi/escape"
4
+ require "cgi/util" if RUBY_VERSION < "3.5"
4
5
 
5
6
  class Object
6
7
  # Alias of <tt>to_s</tt>.
@@ -16,6 +17,11 @@ class Object
16
17
  end
17
18
 
18
19
  class NilClass
20
+ # Returns a CGI-escaped +key+.
21
+ def to_query(key)
22
+ CGI.escape(key.to_param)
23
+ end
24
+
19
25
  # Returns +self+.
20
26
  def to_param
21
27
  self
@@ -145,14 +145,14 @@ class NilClass
145
145
  #
146
146
  # With +try+
147
147
  # @person.try(:children).try(:first).try(:name)
148
- def try(*)
148
+ def try(*, &)
149
149
  nil
150
150
  end
151
151
 
152
152
  # Calling +try!+ on +nil+ always returns +nil+.
153
153
  #
154
154
  # nil.try!(:name) # => nil
155
- def try!(*)
155
+ def try!(*, &)
156
156
  nil
157
157
  end
158
158
  end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/object/acts_like"
4
- require "active_support/core_ext/object/blank"
5
- require "active_support/core_ext/object/duplicable"
6
- require "active_support/core_ext/object/deep_dup"
7
- require "active_support/core_ext/object/try"
8
- require "active_support/core_ext/object/inclusion"
3
+ require_relative "object/acts_like"
4
+ require_relative "object/blank"
5
+ require_relative "object/duplicable"
6
+ require_relative "object/deep_dup"
7
+ require_relative "object/try"
8
+ require_relative "object/inclusion"
9
9
 
10
- require "active_support/core_ext/object/conversions"
11
- require "active_support/core_ext/object/instance_variables"
10
+ require_relative "object/conversions"
11
+ require_relative "object/instance_variables"
12
12
 
13
- require "active_support/core_ext/object/json"
14
- require "active_support/core_ext/object/to_param"
15
- require "active_support/core_ext/object/to_query"
16
- require "active_support/core_ext/object/with"
17
- require "active_support/core_ext/object/with_options"
13
+ require_relative "object/json"
14
+ require_relative "object/to_param"
15
+ require_relative "object/to_query"
16
+ require_relative "object/with"
17
+ require_relative "object/with_options"
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/pathname/blank"
4
- require "active_support/core_ext/pathname/existence"
3
+ require_relative "pathname/blank"
4
+ require_relative "pathname/existence"
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Range
4
- # Compare two ranges and see if they overlap each other
5
- # (1..5).overlap?(4..6) # => true
6
- # (1..5).overlap?(7..9) # => false
7
4
  unless Range.method_defined?(:overlap?) # Ruby 3.3+
5
+ # Compare two ranges and see if they overlap each other
6
+ # (1..5).overlap?(4..6) # => true
7
+ # (1..5).overlap?(7..9) # => false
8
8
  def overlap?(other)
9
9
  raise TypeError unless other.is_a? Range
10
10
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Range
4
+ # Returns the sole item in the range. If there are no items, or more
5
+ # than one item, raises Enumerable::SoleItemExpectedError.
6
+ #
7
+ # (1..1).sole # => 1
8
+ # (2..1).sole # => Enumerable::SoleItemExpectedError: no item found
9
+ # (..1).sole # => Enumerable::SoleItemExpectedError: infinite range cannot represent a sole item
10
+ def sole
11
+ if self.begin.nil? || self.end.nil?
12
+ raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "infinite range '#{inspect}' cannot represent a sole item"
13
+ end
14
+
15
+ super
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/range/conversions"
4
- require "active_support/core_ext/range/compare_range"
5
- require "active_support/core_ext/range/overlap"
6
- require "active_support/core_ext/range/each"
3
+ require_relative "range/conversions"
4
+ require_relative "range/compare_range"
5
+ require_relative "range/overlap"
6
+ require_relative "range/sole"
@@ -16,8 +16,18 @@ module SecureRandom
16
16
  #
17
17
  # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
18
18
  # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
19
- def self.base58(n = 16)
20
- SecureRandom.alphanumeric(n, chars: BASE58_ALPHABET)
19
+ if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version
20
+ def self.base58(n = 16)
21
+ alphanumeric(n, chars: BASE58_ALPHABET)
22
+ end
23
+ else
24
+ def self.base58(n = 16)
25
+ SecureRandom.random_bytes(n).unpack("C*").map do |byte|
26
+ idx = byte % 64
27
+ idx = SecureRandom.random_number(58) if idx >= 58
28
+ BASE58_ALPHABET[idx]
29
+ end.join
30
+ end
21
31
  end
22
32
 
23
33
  # SecureRandom.base36 generates a random base36 string in lowercase.
@@ -31,11 +41,17 @@ module SecureRandom
31
41
  #
32
42
  # p SecureRandom.base36 # => "4kugl2pdqmscqtje"
33
43
  # p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
34
- def self.base36(n = 16)
35
- SecureRandom.random_bytes(n).unpack("C*").map do |byte|
36
- idx = byte % 64
37
- idx = SecureRandom.random_number(36) if idx >= 36
38
- BASE36_ALPHABET[idx]
39
- end.join
44
+ if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version
45
+ def self.base36(n = 16)
46
+ alphanumeric(n, chars: BASE36_ALPHABET)
47
+ end
48
+ else
49
+ def self.base36(n = 16)
50
+ SecureRandom.random_bytes(n).unpack("C*").map do |byte|
51
+ idx = byte % 64
52
+ idx = SecureRandom.random_number(36) if idx >= 36
53
+ BASE36_ALPHABET[idx]
54
+ end.join
55
+ end
40
56
  end
41
57
  end
@@ -88,11 +88,11 @@ class String
88
88
  # characters.
89
89
  #
90
90
  # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size
91
- # => 20
91
+ # # => 20
92
92
  # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize
93
- # => 80
93
+ # # => 80
94
94
  # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20)
95
- # => "🔪🔪🔪🔪…"
95
+ # # => "🔪🔪🔪🔪…"
96
96
  #
97
97
  # The truncated text ends with the <tt>:omission</tt> string, defaulting
98
98
  # to "…", for a total length not exceeding <tt>truncate_to</tt>.
@@ -12,12 +12,12 @@ class String
12
12
  # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
13
13
  #
14
14
  # >> "lj".mb_chars.upcase.to_s
15
- # => "LJ"
15
+ # # => "LJ"
16
16
  #
17
17
  # NOTE: Ruby 2.4 and later support native Unicode case mappings:
18
18
  #
19
19
  # >> "lj".upcase
20
- # => "LJ"
20
+ # # => "LJ"
21
21
  #
22
22
  # == \Method chaining
23
23
  #
@@ -35,7 +35,16 @@ class String
35
35
  # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
36
36
  # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
37
37
  def mb_chars
38
- ActiveSupport::Multibyte.proxy_class.new(self)
38
+ ActiveSupport.deprecator.warn(
39
+ "String#mb_chars is deprecated and will be removed in Rails 8.2. " \
40
+ "Use normal string methods instead."
41
+ )
42
+
43
+ if ActiveSupport::Multibyte.proxy_class == ActiveSupport::Multibyte::Chars
44
+ ActiveSupport::Multibyte::Chars.new(self, deprecation: false)
45
+ else
46
+ ActiveSupport::Multibyte.proxy_class.new(self)
47
+ end
39
48
  end
40
49
 
41
50
  # Returns +true+ if string has utf_8 encoding.