activesupport 6.1.4.1 → 7.0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -395
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +148 -37
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +68 -85
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +299 -147
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +112 -38
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/json.rb +30 -25
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +94 -38
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +13 -8
- data/lib/active_support/core_ext/time/conversions.rb +13 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
- data/lib/active_support/core_ext/time/zones.rb +10 -26
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +31 -14
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/disallowed.rb +3 -3
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +45 -3
- data/lib/active_support/encrypted_file.rb +21 -10
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -12
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +29 -55
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +23 -23
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +4 -5
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +20 -11
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +12 -12
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +43 -22
- data/lib/active_support/values/time_zone.rb +35 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +26 -23
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -1,8 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module ActiveSupport
|
4
|
+
module EnumerableCoreExt # :nodoc:
|
5
|
+
module Constants
|
6
|
+
private
|
7
|
+
def const_missing(name)
|
8
|
+
if name == :SoleItemExpectedError
|
9
|
+
::ActiveSupport::EnumerableCoreExt::SoleItemExpectedError
|
10
|
+
else
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
3
18
|
module Enumerable
|
4
|
-
|
5
|
-
|
19
|
+
# Error generated by +sole+ when called on an enumerable that doesn't have
|
20
|
+
# exactly one item.
|
21
|
+
class SoleItemExpectedError < StandardError; end
|
22
|
+
|
23
|
+
# HACK: For performance reasons, Enumerable shouldn't have any constants of its own.
|
24
|
+
# So we move SoleItemExpectedError into ActiveSupport::EnumerableCoreExt.
|
25
|
+
ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError)
|
26
|
+
singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants)
|
6
27
|
|
7
28
|
# Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
|
8
29
|
# when we omit an identity.
|
@@ -16,31 +37,63 @@ module Enumerable
|
|
16
37
|
|
17
38
|
# :startdoc:
|
18
39
|
|
40
|
+
# Calculates the minimum from the extracted elements.
|
41
|
+
#
|
42
|
+
# payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
|
43
|
+
# payments.minimum(:price) # => 5
|
44
|
+
def minimum(key)
|
45
|
+
map(&key).min
|
46
|
+
end
|
47
|
+
|
48
|
+
# Calculates the maximum from the extracted elements.
|
49
|
+
#
|
50
|
+
# payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
|
51
|
+
# payments.maximum(:price) # => 15
|
52
|
+
def maximum(key)
|
53
|
+
map(&key).max
|
54
|
+
end
|
55
|
+
|
19
56
|
# Calculates a sum from the elements.
|
20
57
|
#
|
21
|
-
#
|
22
|
-
#
|
58
|
+
# payments.sum { |p| p.price * p.tax_rate }
|
59
|
+
# payments.sum(&:price)
|
23
60
|
#
|
24
61
|
# The latter is a shortcut for:
|
25
62
|
#
|
26
|
-
#
|
63
|
+
# payments.inject(0) { |sum, p| sum + p.price }
|
27
64
|
#
|
28
65
|
# It can also calculate the sum without the use of a block.
|
29
66
|
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
67
|
+
# [5, 15, 10].sum # => 30
|
68
|
+
# ['foo', 'bar'].sum('') # => "foobar"
|
69
|
+
# [[1, 2], [3, 1, 5]].sum([]) # => [1, 2, 3, 1, 5]
|
33
70
|
#
|
34
71
|
# The default sum of an empty list is zero. You can override this default:
|
35
72
|
#
|
36
|
-
#
|
73
|
+
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
37
74
|
def sum(identity = nil, &block)
|
38
75
|
if identity
|
39
76
|
_original_sum_with_required_identity(identity, &block)
|
40
77
|
elsif block_given?
|
41
|
-
map(&block).sum
|
78
|
+
map(&block).sum
|
42
79
|
else
|
43
|
-
|
80
|
+
first = true
|
81
|
+
|
82
|
+
reduce(nil) do |sum, value|
|
83
|
+
if first
|
84
|
+
first = false
|
85
|
+
|
86
|
+
unless value.is_a?(Numeric) || value.respond_to?(:coerce)
|
87
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
88
|
+
Rails 7.0 has deprecated Enumerable.sum in favor of Ruby's native implementation available since 2.4.
|
89
|
+
Sum of non-numeric elements requires an initial argument.
|
90
|
+
MSG
|
91
|
+
end
|
92
|
+
value
|
93
|
+
else
|
94
|
+
sum + value
|
95
|
+
end
|
96
|
+
end || 0
|
44
97
|
end
|
45
98
|
end
|
46
99
|
|
@@ -75,17 +128,17 @@ module Enumerable
|
|
75
128
|
#
|
76
129
|
# %i( created_at updated_at ).index_with(Time.now)
|
77
130
|
# # => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 }
|
78
|
-
def index_with(default =
|
131
|
+
def index_with(default = (no_default = true))
|
79
132
|
if block_given?
|
80
133
|
result = {}
|
81
134
|
each { |elem| result[elem] = yield(elem) }
|
82
135
|
result
|
83
|
-
elsif
|
136
|
+
elsif no_default
|
137
|
+
to_enum(:index_with) { size if respond_to?(:size) }
|
138
|
+
else
|
84
139
|
result = {}
|
85
140
|
each { |elem| result[elem] = default }
|
86
141
|
result
|
87
|
-
else
|
88
|
-
to_enum(:index_with) { size if respond_to?(:size) }
|
89
142
|
end
|
90
143
|
end
|
91
144
|
|
@@ -96,8 +149,8 @@ module Enumerable
|
|
96
149
|
def many?
|
97
150
|
cnt = 0
|
98
151
|
if block_given?
|
99
|
-
any? do |
|
100
|
-
cnt += 1 if yield
|
152
|
+
any? do |*args|
|
153
|
+
cnt += 1 if yield(*args)
|
101
154
|
cnt > 1
|
102
155
|
end
|
103
156
|
else
|
@@ -136,11 +189,7 @@ module Enumerable
|
|
136
189
|
elements.flatten!(1)
|
137
190
|
reject { |element| elements.include?(element) }
|
138
191
|
end
|
139
|
-
|
140
|
-
# Alias for #excluding.
|
141
|
-
def without(*elements)
|
142
|
-
excluding(*elements)
|
143
|
-
end
|
192
|
+
alias :without :excluding
|
144
193
|
|
145
194
|
# Extract the given key from each element in the enumerable.
|
146
195
|
#
|
@@ -178,40 +227,66 @@ module Enumerable
|
|
178
227
|
# Returns a new +Array+ without the blank items.
|
179
228
|
# Uses Object#blank? for determining if an item is blank.
|
180
229
|
#
|
181
|
-
#
|
182
|
-
#
|
230
|
+
# [1, "", nil, 2, " ", [], {}, false, true].compact_blank
|
231
|
+
# # => [1, 2, true]
|
183
232
|
#
|
184
|
-
#
|
185
|
-
#
|
233
|
+
# Set.new([nil, "", 1, false]).compact_blank
|
234
|
+
# # => [1]
|
186
235
|
#
|
187
236
|
# When called on a +Hash+, returns a new +Hash+ without the blank values.
|
188
237
|
#
|
189
|
-
#
|
190
|
-
#
|
238
|
+
# { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
|
239
|
+
# # => { b: 1, f: true }
|
191
240
|
def compact_blank
|
192
241
|
reject(&:blank?)
|
193
242
|
end
|
243
|
+
|
244
|
+
# Returns a new +Array+ where the order has been set to that provided in the +series+, based on the +key+ of the
|
245
|
+
# objects in the original enumerable.
|
246
|
+
#
|
247
|
+
# [ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ])
|
248
|
+
# # => [ Person.find(1), Person.find(5), Person.find(3) ]
|
249
|
+
#
|
250
|
+
# If the +series+ include keys that have no corresponding element in the Enumerable, these are ignored.
|
251
|
+
# If the Enumerable has additional elements that aren't named in the +series+, these are not included in the result.
|
252
|
+
def in_order_of(key, series)
|
253
|
+
group_by(&key).values_at(*series).flatten(1).compact
|
254
|
+
end
|
255
|
+
|
256
|
+
# Returns the sole item in the enumerable. If there are no items, or more
|
257
|
+
# than one item, raises +Enumerable::SoleItemExpectedError+.
|
258
|
+
#
|
259
|
+
# ["x"].sole # => "x"
|
260
|
+
# Set.new.sole # => Enumerable::SoleItemExpectedError: no item found
|
261
|
+
# { a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
|
262
|
+
def sole
|
263
|
+
case count
|
264
|
+
when 1 then return first # rubocop:disable Style/RedundantReturn
|
265
|
+
when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
|
266
|
+
when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
|
267
|
+
end
|
268
|
+
end
|
194
269
|
end
|
195
270
|
|
196
271
|
class Hash
|
197
272
|
# Hash#reject has its own definition, so this needs one too.
|
198
|
-
def compact_blank
|
273
|
+
def compact_blank # :nodoc:
|
199
274
|
reject { |_k, v| v.blank? }
|
200
275
|
end
|
201
276
|
|
202
277
|
# Removes all blank values from the +Hash+ in place and returns self.
|
203
278
|
# Uses Object#blank? for determining if a value is blank.
|
204
279
|
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
#
|
280
|
+
# h = { a: "", b: 1, c: nil, d: [], e: false, f: true }
|
281
|
+
# h.compact_blank!
|
282
|
+
# # => { b: 1, f: true }
|
208
283
|
def compact_blank!
|
209
284
|
# use delete_if rather than reject! because it always returns self even if nothing changed
|
210
285
|
delete_if { |_k, v| v.blank? }
|
211
286
|
end
|
212
287
|
end
|
213
288
|
|
214
|
-
class Range
|
289
|
+
class Range # :nodoc:
|
215
290
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
216
291
|
# we have a range of numeric values.
|
217
292
|
def sum(identity = nil)
|
@@ -236,8 +311,7 @@ using Module.new {
|
|
236
311
|
end
|
237
312
|
}
|
238
313
|
|
239
|
-
class Array
|
240
|
-
# Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
|
314
|
+
class Array # :nodoc:
|
241
315
|
def sum(init = nil, &block)
|
242
316
|
if init.is_a?(Numeric) || first.is_a?(Numeric)
|
243
317
|
init ||= 0
|
@@ -250,9 +324,9 @@ class Array #:nodoc:
|
|
250
324
|
# Removes all blank elements from the +Array+ in place and returns self.
|
251
325
|
# Uses Object#blank? for determining if an item is blank.
|
252
326
|
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
327
|
+
# a = [1, "", nil, 2, " ", [], {}, false, true]
|
328
|
+
# a.compact_blank!
|
329
|
+
# # => [1, 2, true]
|
256
330
|
def compact_blank!
|
257
331
|
# use delete_if rather than reject! because it always returns self even if nothing changed
|
258
332
|
delete_if(&:blank?)
|
@@ -53,7 +53,7 @@ class File
|
|
53
53
|
end
|
54
54
|
|
55
55
|
# Private utility method.
|
56
|
-
def self.probe_stat_in(dir)
|
56
|
+
def self.probe_stat_in(dir) # :nodoc:
|
57
57
|
basename = [
|
58
58
|
".permissions_check",
|
59
59
|
Thread.current.object_id,
|
@@ -64,6 +64,8 @@ class File
|
|
64
64
|
file_name = join(dir, basename)
|
65
65
|
FileUtils.touch(file_name)
|
66
66
|
stat(file_name)
|
67
|
+
rescue Errno::ENOENT
|
68
|
+
file_name = nil
|
67
69
|
ensure
|
68
70
|
FileUtils.rm_f(file_name) if file_name
|
69
71
|
end
|
@@ -5,10 +5,10 @@ class Hash
|
|
5
5
|
# This includes the values from the root hash and from all
|
6
6
|
# nested hashes and arrays.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
10
|
+
# hash.deep_transform_values{ |value| value.to_s.upcase }
|
11
|
+
# # => {person: {name: "ROB", age: "28"}}
|
12
12
|
def deep_transform_values(&block)
|
13
13
|
_deep_transform_values_in_object(self, &block)
|
14
14
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "active_support/hash_with_indifferent_access"
|
4
4
|
|
5
5
|
class Hash
|
6
|
-
# Returns an
|
6
|
+
# Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver:
|
7
7
|
#
|
8
8
|
# { a: 1 }.with_indifferent_access['a'] # => 1
|
9
9
|
def with_indifferent_access
|
@@ -13,8 +13,8 @@ class Hash
|
|
13
13
|
# Called when object is nested under an object that receives
|
14
14
|
# #with_indifferent_access. This method will be called on the current object
|
15
15
|
# by the enclosing object and is aliased to #with_indifferent_access by
|
16
|
-
# default. Subclasses of Hash may
|
17
|
-
# converting to an
|
16
|
+
# default. Subclasses of Hash may override this method to return +self+ if
|
17
|
+
# converting to an ActiveSupport::HashWithIndifferentAccess would not be
|
18
18
|
# desirable.
|
19
19
|
#
|
20
20
|
# b = { b: 1 }
|
@@ -58,10 +58,10 @@ class Hash
|
|
58
58
|
# This includes the keys from the root hash and from all
|
59
59
|
# nested hashes and arrays.
|
60
60
|
#
|
61
|
-
#
|
61
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
62
62
|
#
|
63
|
-
#
|
64
|
-
#
|
63
|
+
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
64
|
+
# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
|
65
65
|
def deep_transform_keys(&block)
|
66
66
|
_deep_transform_keys_in_object(self, &block)
|
67
67
|
end
|
@@ -116,7 +116,7 @@ class Hash
|
|
116
116
|
def _deep_transform_keys_in_object(object, &block)
|
117
117
|
case object
|
118
118
|
when Hash
|
119
|
-
object.each_with_object(
|
119
|
+
object.each_with_object(self.class.new) do |(key, value), result|
|
120
120
|
result[yield(key)] = _deep_transform_keys_in_object(value, &block)
|
121
121
|
end
|
122
122
|
when Array
|
@@ -6,12 +6,12 @@ class Integer
|
|
6
6
|
# Ordinalize turns a number into an ordinal string used to denote the
|
7
7
|
# position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# 1.ordinalize # => "1st"
|
10
|
+
# 2.ordinalize # => "2nd"
|
11
|
+
# 1002.ordinalize # => "1002nd"
|
12
|
+
# 1003.ordinalize # => "1003rd"
|
13
|
+
# -11.ordinalize # => "-11th"
|
14
|
+
# -1001.ordinalize # => "-1001st"
|
15
15
|
def ordinalize
|
16
16
|
ActiveSupport::Inflector.ordinalize(self)
|
17
17
|
end
|
@@ -19,12 +19,12 @@ class Integer
|
|
19
19
|
# Ordinal returns the suffix used to denote the position
|
20
20
|
# in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
21
21
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
22
|
+
# 1.ordinal # => "st"
|
23
|
+
# 2.ordinal # => "nd"
|
24
|
+
# 1002.ordinal # => "nd"
|
25
|
+
# 1003.ordinal # => "rd"
|
26
|
+
# -11.ordinal # => "th"
|
27
|
+
# -1001.ordinal # => "st"
|
28
28
|
def ordinal
|
29
29
|
ActiveSupport::Inflector.ordinal(self)
|
30
30
|
end
|
@@ -11,14 +11,14 @@ module Kernel
|
|
11
11
|
# end
|
12
12
|
#
|
13
13
|
# noisy_call # warning voiced
|
14
|
-
def silence_warnings
|
15
|
-
with_warnings(nil)
|
14
|
+
def silence_warnings(&block)
|
15
|
+
with_warnings(nil, &block)
|
16
16
|
end
|
17
17
|
|
18
18
|
# Sets $VERBOSE to +true+ for the duration of the block and back to its
|
19
19
|
# original value afterwards.
|
20
|
-
def enable_warnings
|
21
|
-
with_warnings(true)
|
20
|
+
def enable_warnings(&block)
|
21
|
+
with_warnings(true, &block)
|
22
22
|
end
|
23
23
|
|
24
24
|
# Sets $VERBOSE for the duration of the block and back to its original
|
@@ -1,11 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# == Attribute Accessors per Thread
|
4
|
+
#
|
3
5
|
# Extends the module object with class/module and instance accessors for
|
4
6
|
# class/module attributes, just like the native attr* accessors for instance
|
5
7
|
# attributes, but does so on a per-thread basis.
|
6
8
|
#
|
7
9
|
# So the values are scoped within the Thread.current space under the class name
|
8
10
|
# of the module.
|
11
|
+
#
|
12
|
+
# Note that it can also be scoped per-fiber if +Rails.application.config.active_support.isolation_level+
|
13
|
+
# is set to +:fiber+.
|
9
14
|
class Module
|
10
15
|
# Defines a per-thread class attribute and creates class and instance reader methods.
|
11
16
|
# The underlying per-thread class variable is set to +nil+, if it is not previously defined.
|
@@ -14,9 +19,9 @@ class Module
|
|
14
19
|
# thread_mattr_reader :user
|
15
20
|
# end
|
16
21
|
#
|
17
|
-
# Current.user
|
18
|
-
# Thread.current[:attr_Current_user] = "DHH"
|
22
|
+
# Current.user = "DHH"
|
19
23
|
# Current.user # => "DHH"
|
24
|
+
# Thread.new { Current.user }.value # => nil
|
20
25
|
#
|
21
26
|
# The attribute name must be a valid method name in Ruby.
|
22
27
|
#
|
@@ -41,7 +46,8 @@ class Module
|
|
41
46
|
# to work with inheritance via polymorphism.
|
42
47
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
43
48
|
def self.#{sym}
|
44
|
-
|
49
|
+
@__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
|
50
|
+
::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}]
|
45
51
|
end
|
46
52
|
EOS
|
47
53
|
|
@@ -53,7 +59,7 @@ class Module
|
|
53
59
|
EOS
|
54
60
|
end
|
55
61
|
|
56
|
-
|
62
|
+
::ActiveSupport::IsolatedExecutionState["attr_#{name}_#{sym}"] = default unless default.nil?
|
57
63
|
end
|
58
64
|
end
|
59
65
|
alias :thread_cattr_reader :thread_mattr_reader
|
@@ -84,7 +90,8 @@ class Module
|
|
84
90
|
# to work with inheritance via polymorphism.
|
85
91
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
86
92
|
def self.#{sym}=(obj)
|
87
|
-
|
93
|
+
@__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
|
94
|
+
::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = obj
|
88
95
|
end
|
89
96
|
EOS
|
90
97
|
|
@@ -111,16 +118,18 @@ class Module
|
|
111
118
|
# Account.user # => "DHH"
|
112
119
|
# Account.new.user # => "DHH"
|
113
120
|
#
|
121
|
+
# Unlike +mattr_accessor+, values are *not* shared with subclasses or parent classes.
|
114
122
|
# If a subclass changes the value, the parent class' value is not changed.
|
115
|
-
#
|
116
|
-
# is not changed.
|
123
|
+
# If the parent class changes the value, the value of subclasses is not changed.
|
117
124
|
#
|
118
125
|
# class Customer < Account
|
119
126
|
# end
|
120
127
|
#
|
121
|
-
#
|
122
|
-
# Customer.user
|
123
|
-
#
|
128
|
+
# Account.user # => "DHH"
|
129
|
+
# Customer.user # => nil
|
130
|
+
# Customer.user = "Rafael"
|
131
|
+
# Customer.user # => "Rafael"
|
132
|
+
# Account.user # => "DHH"
|
124
133
|
#
|
125
134
|
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
126
135
|
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
@@ -199,13 +199,7 @@ class Module
|
|
199
199
|
|
200
200
|
# Attribute writer methods only accept one argument. Makes sure []=
|
201
201
|
# methods still accept two arguments.
|
202
|
-
definition =
|
203
|
-
"arg"
|
204
|
-
elsif RUBY_VERSION >= "2.7"
|
205
|
-
"..."
|
206
|
-
else
|
207
|
-
"*args, &block"
|
208
|
-
end
|
202
|
+
definition = /[^\]]=\z/.match?(method) ? "arg" : "..."
|
209
203
|
|
210
204
|
# The following generated method calls the target exactly once, storing
|
211
205
|
# the returned value in a dummy variable.
|
@@ -324,7 +318,7 @@ class Module
|
|
324
318
|
end
|
325
319
|
end
|
326
320
|
end
|
327
|
-
ruby2_keywords(:method_missing)
|
321
|
+
ruby2_keywords(:method_missing)
|
328
322
|
RUBY
|
329
323
|
end
|
330
324
|
end
|
@@ -53,13 +53,7 @@ class NameError
|
|
53
53
|
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
54
54
|
private_constant :UNBOUND_METHOD_MODULE_NAME
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
|
59
|
-
end
|
60
|
-
else
|
61
|
-
def real_mod_name(mod)
|
62
|
-
UNBOUND_METHOD_MODULE_NAME.bind(mod).call
|
63
|
-
end
|
56
|
+
def real_mod_name(mod)
|
57
|
+
UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
|
64
58
|
end
|
65
59
|
end
|