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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +391 -67
- data/README.rdoc +1 -1
- data/lib/active_support/backtrace_cleaner.rb +72 -1
- data/lib/active_support/broadcast_logger.rb +61 -74
- data/lib/active_support/cache/file_store.rb +2 -2
- data/lib/active_support/cache/mem_cache_store.rb +26 -28
- data/lib/active_support/cache/memory_store.rb +5 -5
- data/lib/active_support/cache/null_store.rb +2 -2
- data/lib/active_support/cache/redis_cache_store.rb +37 -31
- data/lib/active_support/cache/strategy/local_cache.rb +72 -27
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
- data/lib/active_support/cache.rb +72 -9
- data/lib/active_support/callbacks.rb +27 -11
- data/lib/active_support/class_attribute.rb +15 -8
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +34 -0
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/conversions.rb +3 -3
- data/lib/active_support/core_ext/array.rb +7 -7
- data/lib/active_support/core_ext/benchmark.rb +4 -11
- data/lib/active_support/core_ext/big_decimal.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +20 -5
- data/lib/active_support/core_ext/class.rb +2 -2
- data/lib/active_support/core_ext/date.rb +5 -5
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
- data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
- data/lib/active_support/core_ext/date_time.rb +5 -5
- data/lib/active_support/core_ext/digest.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +17 -5
- data/lib/active_support/core_ext/erb/util.rb +5 -5
- data/lib/active_support/core_ext/file.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -0
- data/lib/active_support/core_ext/hash.rb +8 -8
- data/lib/active_support/core_ext/integer.rb +3 -3
- data/lib/active_support/core_ext/kernel.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +3 -0
- data/lib/active_support/core_ext/module.rb +11 -11
- data/lib/active_support/core_ext/numeric.rb +3 -3
- data/lib/active_support/core_ext/object/json.rb +8 -1
- data/lib/active_support/core_ext/object/to_query.rb +7 -1
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object.rb +13 -13
- data/lib/active_support/core_ext/pathname.rb +2 -2
- data/lib/active_support/core_ext/range/overlap.rb +3 -3
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +4 -4
- data/lib/active_support/core_ext/securerandom.rb +24 -8
- data/lib/active_support/core_ext/string/filters.rb +3 -3
- data/lib/active_support/core_ext/string/multibyte.rb +12 -3
- data/lib/active_support/core_ext/string/output_safety.rb +19 -12
- data/lib/active_support/core_ext/string.rb +13 -13
- data/lib/active_support/core_ext/symbol.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +0 -7
- data/lib/active_support/core_ext/time/compatibility.rb +2 -27
- data/lib/active_support/core_ext/time.rb +5 -5
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/current_attributes/test_helper.rb +2 -2
- data/lib/active_support/current_attributes.rb +27 -17
- data/lib/active_support/dependencies/interlock.rb +11 -5
- data/lib/active_support/dependencies.rb +6 -1
- data/lib/active_support/deprecation/reporting.rb +4 -2
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/error_reporter.rb +61 -8
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +5 -1
- data/lib/active_support/execution_context.rb +64 -7
- data/lib/active_support/execution_wrapper.rb +1 -1
- data/lib/active_support/file_update_checker.rb +8 -6
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/gzip.rb +1 -0
- data/lib/active_support/hash_with_indifferent_access.rb +47 -24
- data/lib/active_support/i18n_railtie.rb +1 -2
- data/lib/active_support/inflector/inflections.rb +31 -15
- data/lib/active_support/inflector/transliterate.rb +6 -8
- data/lib/active_support/isolated_execution_state.rb +12 -15
- data/lib/active_support/json/decoding.rb +6 -4
- data/lib/active_support/json/encoding.rb +155 -19
- data/lib/active_support/lazy_load_hooks.rb +1 -1
- data/lib/active_support/log_subscriber.rb +2 -6
- data/lib/active_support/logger_thread_safe_level.rb +6 -3
- data/lib/active_support/message_encryptors.rb +54 -2
- data/lib/active_support/message_pack/extensions.rb +5 -0
- data/lib/active_support/message_verifier.rb +9 -0
- data/lib/active_support/message_verifiers.rb +57 -3
- data/lib/active_support/messages/rotation_coordinator.rb +9 -0
- data/lib/active_support/messages/rotator.rb +10 -0
- data/lib/active_support/multibyte/chars.rb +12 -2
- data/lib/active_support/multibyte.rb +4 -0
- data/lib/active_support/notifications/fanout.rb +64 -42
- data/lib/active_support/notifications/instrumenter.rb +1 -1
- data/lib/active_support/railtie.rb +32 -13
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +0 -5
- data/lib/active_support/syntax_error_proxy.rb +3 -0
- data/lib/active_support/test_case.rb +61 -6
- data/lib/active_support/testing/assertions.rb +34 -6
- data/lib/active_support/testing/error_reporter_assertions.rb +18 -1
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +15 -2
- data/lib/active_support/testing/parallelization/worker.rb +4 -2
- data/lib/active_support/testing/parallelization.rb +25 -1
- data/lib/active_support/testing/tests_without_assertions.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +7 -3
- data/lib/active_support/time_with_zone.rb +23 -23
- data/lib/active_support/values/time_zone.rb +8 -1
- data/lib/active_support/xml_mini.rb +3 -2
- data/lib/active_support.rb +20 -15
- metadata +27 -23
- data/lib/active_support/core_ext/range/each.rb +0 -24
- data/lib/active_support/testing/strict_warnings.rb +0 -43
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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})
|
|
112
|
+
if defined?(@#{name})
|
|
113
|
+
@#{name}
|
|
114
|
+
else
|
|
115
|
+
self.class.#{name}
|
|
116
|
+
end
|
|
102
117
|
end
|
|
103
118
|
RUBY
|
|
104
119
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
#
|
|
12
|
-
# as +self
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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"
|
|
@@ -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
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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(
|
|
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('<< Accept & Checkout')
|
|
62
62
|
# # => "<< Accept & Checkout"
|
|
63
63
|
def html_escape_once(s)
|
|
64
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
require_relative "kernel/concern"
|
|
4
|
+
require_relative "kernel/reporting"
|
|
5
|
+
require_relative "kernel/singleton_class"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
11
|
-
|
|
10
|
+
require_relative "object/conversions"
|
|
11
|
+
require_relative "object/instance_variables"
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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,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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
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.
|