activesupport 8.0.2.1 → 8.0.3
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 +52 -3
- data/README.rdoc +1 -1
- data/lib/active_support/broadcast_logger.rb +46 -59
- data/lib/active_support/cache/mem_cache_store.rb +12 -14
- data/lib/active_support/cache.rb +1 -0
- data/lib/active_support/core_ext/benchmark.rb +1 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
- data/lib/active_support/core_ext/enumerable.rb +16 -4
- data/lib/active_support/core_ext/object/to_query.rb +2 -1
- data/lib/active_support/core_ext/object/try.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 +1 -0
- data/lib/active_support/core_ext/string/filters.rb +3 -3
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/current_attributes.rb +13 -6
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +20 -17
- data/lib/active_support/json/decoding.rb +4 -2
- data/lib/active_support/lazy_load_hooks.rb +1 -1
- data/lib/active_support/logger_thread_safe_level.rb +6 -3
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2cdf9736ba5b94841913f95e5e83f01cc82becad9006ed2d75e18f1cc117c43
|
4
|
+
data.tar.gz: 7f8f545780e7ecfece1bdd6af006e504d91e89ad019a1020cd43014a296e7def
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b23ff4bae6aae8f2e154b478c8f36825d0179152a0591591c240ea2b8d6104dcad0b70598a9b42888ab41448a06bc6b69c4ca537c1e5edb386fa81408f25acde
|
7
|
+
data.tar.gz: 84fa236c5c86feff0ae2283888ca7266c5f5d9090474b099c2b9142c082e107062bea571d8197f0138a022d7db7fe08e02f3544ade6cd611de68c35b26b90e75
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,58 @@
|
|
1
|
-
## Rails 8.0.
|
1
|
+
## Rails 8.0.3 (September 22, 2025) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unnecessary reloads with time travel test helpers
|
4
4
|
|
5
|
+
*Jan Grodowski*
|
5
6
|
|
6
|
-
|
7
|
+
* Fix `ActiveSupport::BroadcastLogger` from executing a block argument for each logger (tagged, info, etc.).
|
8
|
+
|
9
|
+
*Jared Armstrong*
|
10
|
+
|
11
|
+
* Make `ActiveSupport::Logger` `#freeze`-friendly.
|
12
|
+
|
13
|
+
*Joshua Young*
|
14
|
+
|
15
|
+
* Fix `ActiveSupport::HashWithIndifferentAccess#transform_keys!` removing defaults.
|
16
|
+
|
17
|
+
*Hartley McGuire*
|
18
|
+
|
19
|
+
* Fix `ActiveSupport::HashWithIndifferentAccess#tranform_keys!` to handle collisions.
|
20
|
+
|
21
|
+
If the transformation would result in a key equal to another not yet transformed one,
|
22
|
+
it would result in keys being lost.
|
23
|
+
|
24
|
+
Before:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
>> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
|
28
|
+
=> {"c" => 1}
|
29
|
+
```
|
30
|
+
|
31
|
+
After:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
>> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
|
35
|
+
=> {"c" => 1, "d" => 2}
|
36
|
+
```
|
37
|
+
|
38
|
+
*Jason T Johnson*, *Jean Boussier*
|
39
|
+
|
40
|
+
* Fix `ActiveSupport::Cache::MemCacheStore#read_multi` to handle network errors.
|
41
|
+
|
42
|
+
This method specifically wasn't handling network errors like other codepaths.
|
43
|
+
|
44
|
+
*Alessandro Dal Grande*
|
45
|
+
|
46
|
+
* Fix configuring `RedisCacheStore` with `raw: true`.
|
47
|
+
|
48
|
+
*fatkodima*
|
49
|
+
|
50
|
+
* Fix `Enumerable#sole` for infinite collections.
|
51
|
+
|
52
|
+
*fatkodima*
|
53
|
+
|
54
|
+
|
55
|
+
## Rails 8.0.2.1 (August 13, 2025) ##
|
7
56
|
|
8
57
|
* No changes.
|
9
58
|
|
data/README.rdoc
CHANGED
@@ -35,6 +35,6 @@ Bug reports for the Ruby on \Rails project can be filed here:
|
|
35
35
|
|
36
36
|
* https://github.com/rails/rails/issues
|
37
37
|
|
38
|
-
Feature requests should be discussed on the
|
38
|
+
Feature requests should be discussed on the rubyonrails-core forum here:
|
39
39
|
|
40
40
|
* https://discuss.rubyonrails.org/c/rubyonrails-core
|
@@ -76,7 +76,6 @@ module ActiveSupport
|
|
76
76
|
|
77
77
|
# Returns all the logger that are part of this broadcast.
|
78
78
|
attr_reader :broadcasts
|
79
|
-
attr_reader :formatter
|
80
79
|
attr_accessor :progname
|
81
80
|
|
82
81
|
def initialize(*loggers)
|
@@ -105,62 +104,36 @@ module ActiveSupport
|
|
105
104
|
@broadcasts.delete(logger)
|
106
105
|
end
|
107
106
|
|
108
|
-
def level
|
109
|
-
@broadcasts.
|
110
|
-
|
111
|
-
|
112
|
-
def <<(message)
|
113
|
-
dispatch { |logger| logger.<<(message) }
|
114
|
-
end
|
115
|
-
|
116
|
-
def add(...)
|
117
|
-
dispatch { |logger| logger.add(...) }
|
118
|
-
end
|
119
|
-
alias_method :log, :add
|
120
|
-
|
121
|
-
def debug(...)
|
122
|
-
dispatch { |logger| logger.debug(...) }
|
123
|
-
end
|
124
|
-
|
125
|
-
def info(...)
|
126
|
-
dispatch { |logger| logger.info(...) }
|
127
|
-
end
|
128
|
-
|
129
|
-
def warn(...)
|
130
|
-
dispatch { |logger| logger.warn(...) }
|
131
|
-
end
|
132
|
-
|
133
|
-
def error(...)
|
134
|
-
dispatch { |logger| logger.error(...) }
|
135
|
-
end
|
136
|
-
|
137
|
-
def fatal(...)
|
138
|
-
dispatch { |logger| logger.fatal(...) }
|
139
|
-
end
|
140
|
-
|
141
|
-
def unknown(...)
|
142
|
-
dispatch { |logger| logger.unknown(...) }
|
107
|
+
def local_level=(level)
|
108
|
+
@broadcasts.each do |logger|
|
109
|
+
logger.local_level = level if logger.respond_to?(:local_level=)
|
110
|
+
end
|
143
111
|
end
|
144
112
|
|
145
|
-
def
|
146
|
-
|
147
|
-
|
148
|
-
@formatter = formatter
|
149
|
-
end
|
113
|
+
def local_level
|
114
|
+
loggers = @broadcasts.select { |logger| logger.respond_to?(:local_level) }
|
150
115
|
|
151
|
-
|
152
|
-
|
116
|
+
loggers.map do |logger|
|
117
|
+
logger.local_level
|
118
|
+
end.first
|
153
119
|
end
|
154
|
-
alias_method :sev_threshold=, :level=
|
155
120
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
121
|
+
LOGGER_METHODS = %w[
|
122
|
+
<< log add debug info warn error fatal unknown
|
123
|
+
level= sev_threshold= close
|
124
|
+
formatter formatter=
|
125
|
+
] # :nodoc:
|
126
|
+
LOGGER_METHODS.each do |method|
|
127
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
128
|
+
def #{method}(...)
|
129
|
+
dispatch(:#{method}, ...)
|
130
|
+
end
|
131
|
+
RUBY
|
160
132
|
end
|
161
133
|
|
162
|
-
|
163
|
-
|
134
|
+
# Returns the lowest level of all the loggers in the broadcast.
|
135
|
+
def level
|
136
|
+
@broadcasts.map(&:level).min
|
164
137
|
end
|
165
138
|
|
166
139
|
# True if the log level allows entries with severity +Logger::DEBUG+ to be written
|
@@ -171,7 +144,7 @@ module ActiveSupport
|
|
171
144
|
|
172
145
|
# Sets the log level to +Logger::DEBUG+ for the whole broadcast.
|
173
146
|
def debug!
|
174
|
-
dispatch
|
147
|
+
dispatch(:debug!)
|
175
148
|
end
|
176
149
|
|
177
150
|
# True if the log level allows entries with severity +Logger::INFO+ to be written
|
@@ -182,7 +155,7 @@ module ActiveSupport
|
|
182
155
|
|
183
156
|
# Sets the log level to +Logger::INFO+ for the whole broadcast.
|
184
157
|
def info!
|
185
|
-
dispatch
|
158
|
+
dispatch(:info!)
|
186
159
|
end
|
187
160
|
|
188
161
|
# True if the log level allows entries with severity +Logger::WARN+ to be written
|
@@ -193,7 +166,7 @@ module ActiveSupport
|
|
193
166
|
|
194
167
|
# Sets the log level to +Logger::WARN+ for the whole broadcast.
|
195
168
|
def warn!
|
196
|
-
dispatch
|
169
|
+
dispatch(:warn!)
|
197
170
|
end
|
198
171
|
|
199
172
|
# True if the log level allows entries with severity +Logger::ERROR+ to be written
|
@@ -204,7 +177,7 @@ module ActiveSupport
|
|
204
177
|
|
205
178
|
# Sets the log level to +Logger::ERROR+ for the whole broadcast.
|
206
179
|
def error!
|
207
|
-
dispatch
|
180
|
+
dispatch(:error!)
|
208
181
|
end
|
209
182
|
|
210
183
|
# True if the log level allows entries with severity +Logger::FATAL+ to be written
|
@@ -215,21 +188,35 @@ module ActiveSupport
|
|
215
188
|
|
216
189
|
# Sets the log level to +Logger::FATAL+ for the whole broadcast.
|
217
190
|
def fatal!
|
218
|
-
dispatch
|
191
|
+
dispatch(:fatal!)
|
219
192
|
end
|
220
193
|
|
221
194
|
def initialize_copy(other)
|
222
195
|
@broadcasts = []
|
223
196
|
@progname = other.progname.dup
|
224
|
-
@formatter = other.formatter.dup
|
225
197
|
|
226
198
|
broadcast_to(*other.broadcasts.map(&:dup))
|
227
199
|
end
|
228
200
|
|
229
201
|
private
|
230
|
-
def dispatch(&block)
|
231
|
-
|
232
|
-
|
202
|
+
def dispatch(method, *args, **kwargs, &block)
|
203
|
+
if block_given?
|
204
|
+
# Maintain semantics that the first logger yields the block
|
205
|
+
# as normal, but subsequent loggers won't re-execute the block.
|
206
|
+
# Instead, the initial result is immediately returned.
|
207
|
+
called, result = false, nil
|
208
|
+
block = proc { |*args, **kwargs|
|
209
|
+
if called then result
|
210
|
+
else
|
211
|
+
called = true
|
212
|
+
result = yield(*args, **kwargs)
|
213
|
+
end
|
214
|
+
}
|
215
|
+
end
|
216
|
+
|
217
|
+
@broadcasts.map { |logger|
|
218
|
+
logger.send(method, *args, **kwargs, &block)
|
219
|
+
}.first
|
233
220
|
end
|
234
221
|
|
235
222
|
def method_missing(name, ...)
|
@@ -212,26 +212,24 @@ module ActiveSupport
|
|
212
212
|
def read_multi_entries(names, **options)
|
213
213
|
keys_to_names = names.index_by { |name| normalize_key(name, options) }
|
214
214
|
|
215
|
-
|
216
|
-
@data.with { |c| c.get_multi(keys_to_names.keys) }
|
217
|
-
rescue Dalli::UnmarshalError
|
218
|
-
{}
|
219
|
-
end
|
215
|
+
rescue_error_with({}) do
|
216
|
+
raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) }
|
220
217
|
|
221
|
-
|
218
|
+
values = {}
|
222
219
|
|
223
|
-
|
224
|
-
|
220
|
+
raw_values.each do |key, value|
|
221
|
+
entry = deserialize_entry(value, raw: options[:raw])
|
225
222
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
223
|
+
unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
|
224
|
+
begin
|
225
|
+
values[keys_to_names[key]] = entry.value
|
226
|
+
rescue DeserializationError
|
227
|
+
end
|
230
228
|
end
|
231
229
|
end
|
232
|
-
end
|
233
230
|
|
234
|
-
|
231
|
+
values
|
232
|
+
end
|
235
233
|
end
|
236
234
|
|
237
235
|
# Delete an entry from the cache.
|
data/lib/active_support/cache.rb
CHANGED
@@ -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
|
@@ -209,10 +209,22 @@ module Enumerable
|
|
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
|
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
|
@@ -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,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
|
@@ -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
|
#
|
@@ -108,15 +108,18 @@ module ActiveSupport
|
|
108
108
|
# ==== Options
|
109
109
|
#
|
110
110
|
# * <tt>:default</tt> - The default value for the attributes. If the value
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
111
|
+
# is a proc or lambda, it will be called whenever an instance is
|
112
|
+
# constructed. Otherwise, the value will be duplicated with +#dup+.
|
113
|
+
# Default values are re-assigned when the attributes are reset.
|
114
114
|
def attribute(*names, default: NOT_SET)
|
115
115
|
invalid_attribute_names = names.map(&:to_sym) & INVALID_ATTRIBUTE_NAMES
|
116
116
|
if invalid_attribute_names.any?
|
117
117
|
raise ArgumentError, "Restricted attribute names: #{invalid_attribute_names.join(", ")}"
|
118
118
|
end
|
119
119
|
|
120
|
+
Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "")
|
121
|
+
Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value")
|
122
|
+
|
120
123
|
ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
|
121
124
|
names.each do |name|
|
122
125
|
owner.define_cached_method(name, namespace: :current_attributes) do |batch|
|
@@ -134,9 +137,6 @@ module ActiveSupport
|
|
134
137
|
end
|
135
138
|
end
|
136
139
|
|
137
|
-
Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "")
|
138
|
-
Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value")
|
139
|
-
|
140
140
|
self.defaults = defaults.merge(names.index_with { default })
|
141
141
|
end
|
142
142
|
|
@@ -185,9 +185,16 @@ module ActiveSupport
|
|
185
185
|
|
186
186
|
def method_added(name)
|
187
187
|
super
|
188
|
+
|
189
|
+
# We try to generate instance delegators early to not rely on method_missing.
|
188
190
|
return if name == :initialize
|
191
|
+
|
192
|
+
# If the added method isn't public, we don't delegate it.
|
189
193
|
return unless public_method_defined?(name)
|
194
|
+
|
195
|
+
# If we already have a class method by that name, we don't override it.
|
190
196
|
return if singleton_class.method_defined?(name) || singleton_class.private_method_defined?(name)
|
197
|
+
|
191
198
|
Delegation.generate(singleton_class, [name], to: :instance, as: self, nilable: false)
|
192
199
|
end
|
193
200
|
end
|
@@ -120,7 +120,7 @@ module ActiveSupport
|
|
120
120
|
# healthy to consider this edge case because with mtimes in the future
|
121
121
|
# reloading is not triggered.
|
122
122
|
def max_mtime(paths)
|
123
|
-
time_now = Time.
|
123
|
+
time_now = Time.at(0, Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond), :nanosecond)
|
124
124
|
max_mtime = nil
|
125
125
|
|
126
126
|
# Time comparisons are performed with #compare_without_coercion because
|
@@ -262,9 +262,7 @@ module ActiveSupport
|
|
262
262
|
# hash[:a][:c] # => "c"
|
263
263
|
# dup[:a][:c] # => "c"
|
264
264
|
def dup
|
265
|
-
self.class.new(self)
|
266
|
-
set_defaults(new_hash)
|
267
|
-
end
|
265
|
+
copy_defaults(self.class.new(self))
|
268
266
|
end
|
269
267
|
|
270
268
|
# This method has the same semantics of +update+, except it does not
|
@@ -338,21 +336,26 @@ module ActiveSupport
|
|
338
336
|
NOT_GIVEN = Object.new # :nodoc:
|
339
337
|
|
340
338
|
def transform_keys(hash = NOT_GIVEN, &block)
|
341
|
-
|
342
|
-
|
339
|
+
if NOT_GIVEN.equal?(hash)
|
340
|
+
if block_given?
|
341
|
+
self.class.new(super(&block))
|
342
|
+
else
|
343
|
+
to_enum(:transform_keys)
|
344
|
+
end
|
345
|
+
else
|
346
|
+
self.class.new(super)
|
347
|
+
end
|
343
348
|
end
|
344
349
|
|
345
350
|
def transform_keys!(hash = NOT_GIVEN, &block)
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
elsif block_given?
|
353
|
-
keys.each { |key| self[hash[key] || yield(key)] = delete(key) }
|
351
|
+
if NOT_GIVEN.equal?(hash)
|
352
|
+
if block_given?
|
353
|
+
replace(copy_defaults(transform_keys(&block)))
|
354
|
+
else
|
355
|
+
return to_enum(:transform_keys!)
|
356
|
+
end
|
354
357
|
else
|
355
|
-
|
358
|
+
replace(copy_defaults(transform_keys(hash, &block)))
|
356
359
|
end
|
357
360
|
|
358
361
|
self
|
@@ -376,8 +379,7 @@ module ActiveSupport
|
|
376
379
|
def to_hash
|
377
380
|
copy = Hash[self]
|
378
381
|
copy.transform_values! { |v| convert_value_to_hash(v) }
|
379
|
-
|
380
|
-
copy
|
382
|
+
copy_defaults(copy)
|
381
383
|
end
|
382
384
|
|
383
385
|
def to_proc
|
@@ -413,12 +415,13 @@ module ActiveSupport
|
|
413
415
|
end
|
414
416
|
|
415
417
|
|
416
|
-
def
|
418
|
+
def copy_defaults(target)
|
417
419
|
if default_proc
|
418
420
|
target.default_proc = default_proc.dup
|
419
421
|
else
|
420
422
|
target.default = default
|
421
423
|
end
|
424
|
+
target
|
422
425
|
end
|
423
426
|
|
424
427
|
def update_with_single_argument(other_hash, block)
|
@@ -14,11 +14,13 @@ module ActiveSupport
|
|
14
14
|
DATETIME_REGEX = /\A(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)\z/
|
15
15
|
|
16
16
|
class << self
|
17
|
-
# Parses a JSON string (JavaScript Object Notation) into a
|
17
|
+
# Parses a JSON string (JavaScript Object Notation) into a Ruby object.
|
18
18
|
# See http://www.json.org for more info.
|
19
19
|
#
|
20
20
|
# ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
|
21
|
-
# => {"team" => "rails", "players" => "36"}
|
21
|
+
# # => {"team" => "rails", "players" => "36"}
|
22
|
+
# ActiveSupport::JSON.decode("2.39")
|
23
|
+
# # => 2.39
|
22
24
|
def decode(json)
|
23
25
|
data = ::JSON.parse(json, quirks_mode: true)
|
24
26
|
|
@@ -53,7 +53,7 @@ module ActiveSupport
|
|
53
53
|
# loaded. If the component has already loaded, the block is executed
|
54
54
|
# immediately.
|
55
55
|
#
|
56
|
-
# Options
|
56
|
+
# ==== Options
|
57
57
|
#
|
58
58
|
# * <tt>:yield</tt> - Yields the object that run_load_hooks to +block+.
|
59
59
|
# * <tt>:run_once</tt> - Given +block+ will run only once.
|
@@ -7,6 +7,11 @@ module ActiveSupport
|
|
7
7
|
module LoggerThreadSafeLevel # :nodoc:
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
+
def initialize(...)
|
11
|
+
super
|
12
|
+
@local_level_key = :"logger_thread_safe_level_#{object_id}"
|
13
|
+
end
|
14
|
+
|
10
15
|
def local_level
|
11
16
|
IsolatedExecutionState[local_level_key]
|
12
17
|
end
|
@@ -40,8 +45,6 @@ module ActiveSupport
|
|
40
45
|
end
|
41
46
|
|
42
47
|
private
|
43
|
-
|
44
|
-
@local_level_key ||= :"logger_thread_safe_level_#{object_id}"
|
45
|
-
end
|
48
|
+
attr_reader :local_level_key
|
46
49
|
end
|
47
50
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activesupport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.
|
4
|
+
version: 8.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -329,6 +329,7 @@ files:
|
|
329
329
|
- lib/active_support/core_ext/range/conversions.rb
|
330
330
|
- lib/active_support/core_ext/range/each.rb
|
331
331
|
- lib/active_support/core_ext/range/overlap.rb
|
332
|
+
- lib/active_support/core_ext/range/sole.rb
|
332
333
|
- lib/active_support/core_ext/regexp.rb
|
333
334
|
- lib/active_support/core_ext/securerandom.rb
|
334
335
|
- lib/active_support/core_ext/string.rb
|
@@ -493,10 +494,10 @@ licenses:
|
|
493
494
|
- MIT
|
494
495
|
metadata:
|
495
496
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
496
|
-
changelog_uri: https://github.com/rails/rails/blob/v8.0.
|
497
|
-
documentation_uri: https://api.rubyonrails.org/v8.0.
|
497
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.0.3/activesupport/CHANGELOG.md
|
498
|
+
documentation_uri: https://api.rubyonrails.org/v8.0.3/
|
498
499
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
499
|
-
source_code_uri: https://github.com/rails/rails/tree/v8.0.
|
500
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.0.3/activesupport
|
500
501
|
rubygems_mfa_required: 'true'
|
501
502
|
rdoc_options:
|
502
503
|
- "--encoding"
|