activesupport 5.2.5 → 6.0.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +452 -398
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +27 -1
- data/lib/active_support/cache/file_store.rb +32 -32
- data/lib/active_support/cache/mem_cache_store.rb +12 -7
- data/lib/active_support/cache/memory_store.rb +15 -9
- data/lib/active_support/cache/null_store.rb +8 -3
- data/lib/active_support/cache/redis_cache_store.rb +47 -20
- data/lib/active_support/cache/strategy/local_cache.rb +22 -22
- data/lib/active_support/cache.rb +71 -48
- data/lib/active_support/callbacks.rb +16 -8
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/conversions.rb +5 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
- data/lib/active_support/core_ext/enumerable.rb +97 -73
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +41 -8
- data/lib/active_support/core_ext/module/introspection.rb +38 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +2 -1
- data/lib/active_support/core_ext/object/try.rb +17 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +28 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/each.rb +0 -1
- data/lib/active_support/core_ext/range/include_range.rb +6 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +68 -10
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +34 -3
- data/lib/active_support/core_ext/uri.rb +1 -0
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +74 -18
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +17 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/descendants_tracker.rb +55 -9
- data/lib/active_support/duration/iso8601_parser.rb +2 -4
- data/lib/active_support/duration/iso8601_serializer.rb +3 -5
- data/lib/active_support/duration.rb +7 -8
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +3 -2
- data/lib/active_support/evented_file_update_checker.rb +39 -10
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +22 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +13 -1
- data/lib/active_support/inflector/inflections.rb +1 -5
- data/lib/active_support/inflector/methods.rb +16 -29
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -24
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/log_subscriber.rb +31 -9
- data/lib/active_support/logger.rb +1 -16
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +26 -4
- data/lib/active_support/message_encryptor.rb +4 -6
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +11 -2
- data/lib/active_support/messages/rotator.rb +4 -4
- data/lib/active_support/multibyte/chars.rb +29 -49
- data/lib/active_support/multibyte/unicode.rb +44 -282
- data/lib/active_support/notifications/fanout.rb +98 -13
- data/lib/active_support/notifications/instrumenter.rb +80 -9
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/number_helper/number_converter.rb +4 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
- data/lib/active_support/number_helper/rounding_helper.rb +1 -1
- data/lib/active_support/number_helper.rb +11 -0
- data/lib/active_support/option_merger.rb +21 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +5 -1
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -1
- data/lib/active_support/subscriber.rb +65 -26
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/stream.rb +1 -2
- data/lib/active_support/testing/time_helpers.rb +7 -9
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +12 -7
- data/lib/active_support/xml_mini/jdom.rb +2 -3
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- data/lib/active_support/xml_mini.rb +2 -10
- data/lib/active_support.rb +2 -1
- metadata +40 -12
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -50,27 +50,27 @@ module ActiveSupport
|
|
50
50
|
@data.clear
|
51
51
|
end
|
52
52
|
|
53
|
-
def read_entry(key, options)
|
53
|
+
def read_entry(key, **options)
|
54
54
|
@data[key]
|
55
55
|
end
|
56
56
|
|
57
|
-
def read_multi_entries(keys, options)
|
57
|
+
def read_multi_entries(keys, **options)
|
58
58
|
values = {}
|
59
59
|
|
60
60
|
keys.each do |name|
|
61
|
-
entry = read_entry(name, options)
|
61
|
+
entry = read_entry(name, **options)
|
62
62
|
values[name] = entry.value if entry
|
63
63
|
end
|
64
64
|
|
65
65
|
values
|
66
66
|
end
|
67
67
|
|
68
|
-
def write_entry(key, value, options)
|
68
|
+
def write_entry(key, value, **options)
|
69
69
|
@data[key] = value
|
70
70
|
true
|
71
71
|
end
|
72
72
|
|
73
|
-
def delete_entry(key, options)
|
73
|
+
def delete_entry(key, **options)
|
74
74
|
!!@data.delete(key)
|
75
75
|
end
|
76
76
|
|
@@ -92,34 +92,34 @@ module ActiveSupport
|
|
92
92
|
local_cache_key)
|
93
93
|
end
|
94
94
|
|
95
|
-
def clear(options
|
95
|
+
def clear(**options) # :nodoc:
|
96
96
|
return super unless cache = local_cache
|
97
97
|
cache.clear(options)
|
98
98
|
super
|
99
99
|
end
|
100
100
|
|
101
|
-
def cleanup(options
|
101
|
+
def cleanup(**options) # :nodoc:
|
102
102
|
return super unless cache = local_cache
|
103
103
|
cache.clear
|
104
104
|
super
|
105
105
|
end
|
106
106
|
|
107
|
-
def increment(name, amount = 1, options
|
107
|
+
def increment(name, amount = 1, **options) # :nodoc:
|
108
108
|
return super unless local_cache
|
109
109
|
value = bypass_local_cache { super }
|
110
|
-
write_cache_value(name, value, options)
|
110
|
+
write_cache_value(name, value, **options)
|
111
111
|
value
|
112
112
|
end
|
113
113
|
|
114
|
-
def decrement(name, amount = 1, options
|
114
|
+
def decrement(name, amount = 1, **options) # :nodoc:
|
115
115
|
return super unless local_cache
|
116
116
|
value = bypass_local_cache { super }
|
117
|
-
write_cache_value(name, value, options)
|
117
|
+
write_cache_value(name, value, **options)
|
118
118
|
value
|
119
119
|
end
|
120
120
|
|
121
121
|
private
|
122
|
-
def read_entry(key, options)
|
122
|
+
def read_entry(key, **options)
|
123
123
|
if cache = local_cache
|
124
124
|
cache.fetch_entry(key) { super }
|
125
125
|
else
|
@@ -127,42 +127,42 @@ module ActiveSupport
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
def read_multi_entries(keys, options)
|
130
|
+
def read_multi_entries(keys, **options)
|
131
131
|
return super unless local_cache
|
132
132
|
|
133
|
-
local_entries = local_cache.read_multi_entries(keys, options)
|
133
|
+
local_entries = local_cache.read_multi_entries(keys, **options)
|
134
134
|
missed_keys = keys - local_entries.keys
|
135
135
|
|
136
136
|
if missed_keys.any?
|
137
|
-
local_entries.merge!(super(missed_keys, options))
|
137
|
+
local_entries.merge!(super(missed_keys, **options))
|
138
138
|
else
|
139
139
|
local_entries
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
def write_entry(key, entry, options)
|
143
|
+
def write_entry(key, entry, **options)
|
144
144
|
if options[:unless_exist]
|
145
|
-
local_cache.delete_entry(key, options) if local_cache
|
145
|
+
local_cache.delete_entry(key, **options) if local_cache
|
146
146
|
else
|
147
|
-
local_cache.write_entry(key, entry, options) if local_cache
|
147
|
+
local_cache.write_entry(key, entry, **options) if local_cache
|
148
148
|
end
|
149
149
|
|
150
150
|
super
|
151
151
|
end
|
152
152
|
|
153
|
-
def delete_entry(key, options)
|
154
|
-
local_cache.delete_entry(key, options) if local_cache
|
153
|
+
def delete_entry(key, **options)
|
154
|
+
local_cache.delete_entry(key, **options) if local_cache
|
155
155
|
super
|
156
156
|
end
|
157
157
|
|
158
|
-
def write_cache_value(name, value, options)
|
158
|
+
def write_cache_value(name, value, **options)
|
159
159
|
name = normalize_key(name, options)
|
160
160
|
cache = local_cache
|
161
161
|
cache.mute do
|
162
162
|
if value
|
163
163
|
cache.write(name, value, options)
|
164
164
|
else
|
165
|
-
cache.delete(name, options)
|
165
|
+
cache.delete(name, **options)
|
166
166
|
end
|
167
167
|
end
|
168
168
|
end
|
data/lib/active_support/cache.rb
CHANGED
@@ -52,12 +52,13 @@ module ActiveSupport
|
|
52
52
|
#
|
53
53
|
# ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
|
54
54
|
# # => returns MyOwnCacheStore.new
|
55
|
-
def lookup_store(*
|
56
|
-
store, *parameters = *Array.wrap(store_option).flatten
|
57
|
-
|
55
|
+
def lookup_store(store = nil, *parameters)
|
58
56
|
case store
|
59
57
|
when Symbol
|
60
|
-
|
58
|
+
options = parameters.extract_options!
|
59
|
+
retrieve_store_class(store).new(*parameters, **options)
|
60
|
+
when Array
|
61
|
+
lookup_store(*store)
|
61
62
|
when nil
|
62
63
|
ActiveSupport::Cache::MemoryStore.new
|
63
64
|
else
|
@@ -229,6 +230,14 @@ module ActiveSupport
|
|
229
230
|
# ask whether you should force a cache write. Otherwise, it's clearer to
|
230
231
|
# just call <tt>Cache#write</tt>.
|
231
232
|
#
|
233
|
+
# Setting <tt>skip_nil: true</tt> will not cache nil result:
|
234
|
+
#
|
235
|
+
# cache.fetch('foo') { nil }
|
236
|
+
# cache.fetch('bar', skip_nil: true) { nil }
|
237
|
+
# cache.exist?('foo') # => true
|
238
|
+
# cache.exist?('bar') # => false
|
239
|
+
#
|
240
|
+
#
|
232
241
|
# Setting <tt>compress: false</tt> disables compression of the cache entry.
|
233
242
|
#
|
234
243
|
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
@@ -303,14 +312,14 @@ module ActiveSupport
|
|
303
312
|
# :bar
|
304
313
|
# end
|
305
314
|
# cache.fetch('foo') # => "bar"
|
306
|
-
def fetch(name, options = nil)
|
315
|
+
def fetch(name, options = nil, &block)
|
307
316
|
if block_given?
|
308
317
|
options = merged_options(options)
|
309
318
|
key = normalize_key(name, options)
|
310
319
|
|
311
320
|
entry = nil
|
312
321
|
instrument(:read, name, options) do |payload|
|
313
|
-
cached_entry = read_entry(key, options) unless options[:force]
|
322
|
+
cached_entry = read_entry(key, **options) unless options[:force]
|
314
323
|
entry = handle_expired_entry(cached_entry, key, options)
|
315
324
|
entry = nil if entry && entry.mismatched?(normalize_version(name, options))
|
316
325
|
payload[:super_operation] = :fetch if payload
|
@@ -320,7 +329,7 @@ module ActiveSupport
|
|
320
329
|
if entry
|
321
330
|
get_entry_value(entry, name, options)
|
322
331
|
else
|
323
|
-
save_block_result_to_cache(name, options)
|
332
|
+
save_block_result_to_cache(name, options, &block)
|
324
333
|
end
|
325
334
|
elsif options && options[:force]
|
326
335
|
raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
|
@@ -333,8 +342,9 @@ module ActiveSupport
|
|
333
342
|
# the cache with the given key, then that data is returned. Otherwise,
|
334
343
|
# +nil+ is returned.
|
335
344
|
#
|
336
|
-
# Note, if data was written with the <tt>:expires_in
|
337
|
-
# both of these conditions are applied before
|
345
|
+
# Note, if data was written with the <tt>:expires_in</tt> or
|
346
|
+
# <tt>:version</tt> options, both of these conditions are applied before
|
347
|
+
# the data is returned.
|
338
348
|
#
|
339
349
|
# Options are passed to the underlying cache implementation.
|
340
350
|
def read(name, options = nil)
|
@@ -343,11 +353,11 @@ module ActiveSupport
|
|
343
353
|
version = normalize_version(name, options)
|
344
354
|
|
345
355
|
instrument(:read, name, options) do |payload|
|
346
|
-
entry = read_entry(key, options)
|
356
|
+
entry = read_entry(key, **options)
|
347
357
|
|
348
358
|
if entry
|
349
359
|
if entry.expired?
|
350
|
-
delete_entry(key, options)
|
360
|
+
delete_entry(key, **options)
|
351
361
|
payload[:hit] = false if payload
|
352
362
|
nil
|
353
363
|
elsif entry.mismatched?(version)
|
@@ -375,7 +385,7 @@ module ActiveSupport
|
|
375
385
|
options = merged_options(options)
|
376
386
|
|
377
387
|
instrument :read_multi, names, options do |payload|
|
378
|
-
read_multi_entries(names, options).tap do |results|
|
388
|
+
read_multi_entries(names, **options).tap do |results|
|
379
389
|
payload[:hits] = results.keys
|
380
390
|
end
|
381
391
|
end
|
@@ -387,10 +397,10 @@ module ActiveSupport
|
|
387
397
|
|
388
398
|
instrument :write_multi, hash, options do |payload|
|
389
399
|
entries = hash.each_with_object({}) do |(name, value), memo|
|
390
|
-
memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
400
|
+
memo[normalize_key(name, options)] = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
391
401
|
end
|
392
402
|
|
393
|
-
write_multi_entries entries, options
|
403
|
+
write_multi_entries entries, **options
|
394
404
|
end
|
395
405
|
end
|
396
406
|
|
@@ -402,8 +412,6 @@ module ActiveSupport
|
|
402
412
|
# to the cache. If you do not want to write the cache when the cache is
|
403
413
|
# not found, use #read_multi.
|
404
414
|
#
|
405
|
-
# Options are passed to the underlying cache implementation.
|
406
|
-
#
|
407
415
|
# Returns a hash with the data for each of the names. For example:
|
408
416
|
#
|
409
417
|
# cache.write("bim", "bam")
|
@@ -413,6 +421,17 @@ module ActiveSupport
|
|
413
421
|
# # => { "bim" => "bam",
|
414
422
|
# # "unknown_key" => "Fallback value for key: unknown_key" }
|
415
423
|
#
|
424
|
+
# Options are passed to the underlying cache implementation. For example:
|
425
|
+
#
|
426
|
+
# cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
|
427
|
+
# "buzz"
|
428
|
+
# end
|
429
|
+
# # => {"fizz"=>"buzz"}
|
430
|
+
# cache.read("fizz")
|
431
|
+
# # => "buzz"
|
432
|
+
# sleep(6)
|
433
|
+
# cache.read("fizz")
|
434
|
+
# # => nil
|
416
435
|
def fetch_multi(*names)
|
417
436
|
raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
|
418
437
|
|
@@ -420,18 +439,18 @@ module ActiveSupport
|
|
420
439
|
options = merged_options(options)
|
421
440
|
|
422
441
|
instrument :read_multi, names, options do |payload|
|
423
|
-
read_multi_entries(names, options)
|
424
|
-
|
425
|
-
|
442
|
+
reads = read_multi_entries(names, **options)
|
443
|
+
writes = {}
|
444
|
+
ordered = names.each_with_object({}) do |name, hash|
|
445
|
+
hash[name] = reads.fetch(name) { writes[name] = yield(name) }
|
446
|
+
end
|
426
447
|
|
427
|
-
|
448
|
+
payload[:hits] = reads.keys
|
449
|
+
payload[:super_operation] = :fetch_multi
|
428
450
|
|
429
|
-
|
430
|
-
results[name] = writes[name] = yield(name)
|
431
|
-
end
|
451
|
+
write_multi(writes, options)
|
432
452
|
|
433
|
-
|
434
|
-
end
|
453
|
+
ordered
|
435
454
|
end
|
436
455
|
end
|
437
456
|
|
@@ -442,8 +461,8 @@ module ActiveSupport
|
|
442
461
|
options = merged_options(options)
|
443
462
|
|
444
463
|
instrument(:write, name, options) do
|
445
|
-
entry = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
446
|
-
write_entry(normalize_key(name, options), entry, options)
|
464
|
+
entry = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
465
|
+
write_entry(normalize_key(name, options), entry, **options)
|
447
466
|
end
|
448
467
|
end
|
449
468
|
|
@@ -454,7 +473,7 @@ module ActiveSupport
|
|
454
473
|
options = merged_options(options)
|
455
474
|
|
456
475
|
instrument(:delete, name) do
|
457
|
-
delete_entry(normalize_key(name, options), options)
|
476
|
+
delete_entry(normalize_key(name, options), **options)
|
458
477
|
end
|
459
478
|
end
|
460
479
|
|
@@ -465,7 +484,7 @@ module ActiveSupport
|
|
465
484
|
options = merged_options(options)
|
466
485
|
|
467
486
|
instrument(:exist?, name) do
|
468
|
-
entry = read_entry(normalize_key(name, options), options)
|
487
|
+
entry = read_entry(normalize_key(name, options), **options)
|
469
488
|
(entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
|
470
489
|
end
|
471
490
|
end
|
@@ -474,7 +493,7 @@ module ActiveSupport
|
|
474
493
|
#
|
475
494
|
# Options are passed to the underlying cache implementation.
|
476
495
|
#
|
477
|
-
#
|
496
|
+
# Some implementations may not support this method.
|
478
497
|
def delete_matched(matcher, options = nil)
|
479
498
|
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
480
499
|
end
|
@@ -483,7 +502,7 @@ module ActiveSupport
|
|
483
502
|
#
|
484
503
|
# Options are passed to the underlying cache implementation.
|
485
504
|
#
|
486
|
-
#
|
505
|
+
# Some implementations may not support this method.
|
487
506
|
def increment(name, amount = 1, options = nil)
|
488
507
|
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
489
508
|
end
|
@@ -492,7 +511,7 @@ module ActiveSupport
|
|
492
511
|
#
|
493
512
|
# Options are passed to the underlying cache implementation.
|
494
513
|
#
|
495
|
-
#
|
514
|
+
# Some implementations may not support this method.
|
496
515
|
def decrement(name, amount = 1, options = nil)
|
497
516
|
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
498
517
|
end
|
@@ -501,7 +520,7 @@ module ActiveSupport
|
|
501
520
|
#
|
502
521
|
# Options are passed to the underlying cache implementation.
|
503
522
|
#
|
504
|
-
#
|
523
|
+
# Some implementations may not support this method.
|
505
524
|
def cleanup(options = nil)
|
506
525
|
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
507
526
|
end
|
@@ -511,7 +530,7 @@ module ActiveSupport
|
|
511
530
|
#
|
512
531
|
# The options hash is passed to the underlying cache implementation.
|
513
532
|
#
|
514
|
-
#
|
533
|
+
# Some implementations may not support this method.
|
515
534
|
def clear(options = nil)
|
516
535
|
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
517
536
|
end
|
@@ -538,28 +557,28 @@ module ActiveSupport
|
|
538
557
|
|
539
558
|
# Reads an entry from the cache implementation. Subclasses must implement
|
540
559
|
# this method.
|
541
|
-
def read_entry(key, options)
|
560
|
+
def read_entry(key, **options)
|
542
561
|
raise NotImplementedError.new
|
543
562
|
end
|
544
563
|
|
545
564
|
# Writes an entry to the cache implementation. Subclasses must implement
|
546
565
|
# this method.
|
547
|
-
def write_entry(key, entry, options)
|
566
|
+
def write_entry(key, entry, **options)
|
548
567
|
raise NotImplementedError.new
|
549
568
|
end
|
550
569
|
|
551
570
|
# Reads multiple entries from the cache implementation. Subclasses MAY
|
552
571
|
# implement this method.
|
553
|
-
def read_multi_entries(names, options)
|
572
|
+
def read_multi_entries(names, **options)
|
554
573
|
results = {}
|
555
574
|
names.each do |name|
|
556
575
|
key = normalize_key(name, options)
|
557
576
|
version = normalize_version(name, options)
|
558
|
-
entry = read_entry(key, options)
|
577
|
+
entry = read_entry(key, **options)
|
559
578
|
|
560
579
|
if entry
|
561
580
|
if entry.expired?
|
562
|
-
delete_entry(key, options)
|
581
|
+
delete_entry(key, **options)
|
563
582
|
elsif entry.mismatched?(version)
|
564
583
|
# Skip mismatched versions
|
565
584
|
else
|
@@ -572,24 +591,28 @@ module ActiveSupport
|
|
572
591
|
|
573
592
|
# Writes multiple entries to the cache implementation. Subclasses MAY
|
574
593
|
# implement this method.
|
575
|
-
def write_multi_entries(hash, options)
|
594
|
+
def write_multi_entries(hash, **options)
|
576
595
|
hash.each do |key, entry|
|
577
|
-
write_entry key, entry, options
|
596
|
+
write_entry key, entry, **options
|
578
597
|
end
|
579
598
|
end
|
580
599
|
|
581
600
|
# Deletes an entry from the cache implementation. Subclasses must
|
582
601
|
# implement this method.
|
583
|
-
def delete_entry(key, options)
|
602
|
+
def delete_entry(key, **options)
|
584
603
|
raise NotImplementedError.new
|
585
604
|
end
|
586
605
|
|
587
606
|
# Merges the default options with ones specific to a method call.
|
588
607
|
def merged_options(call_options)
|
589
608
|
if call_options
|
590
|
-
options.
|
609
|
+
if options.empty?
|
610
|
+
call_options
|
611
|
+
else
|
612
|
+
options.merge(call_options)
|
613
|
+
end
|
591
614
|
else
|
592
|
-
options
|
615
|
+
options
|
593
616
|
end
|
594
617
|
end
|
595
618
|
|
@@ -634,7 +657,7 @@ module ActiveSupport
|
|
634
657
|
if key.size > 1
|
635
658
|
key = key.collect { |element| expanded_key(element) }
|
636
659
|
else
|
637
|
-
key = key.first
|
660
|
+
key = expanded_key(key.first)
|
638
661
|
end
|
639
662
|
when Hash
|
640
663
|
key = key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }
|
@@ -677,7 +700,7 @@ module ActiveSupport
|
|
677
700
|
entry.expires_at = Time.now + race_ttl
|
678
701
|
write_entry(key, entry, expires_in: race_ttl * 2)
|
679
702
|
else
|
680
|
-
delete_entry(key, options)
|
703
|
+
delete_entry(key, **options)
|
681
704
|
end
|
682
705
|
entry = nil
|
683
706
|
end
|
@@ -685,7 +708,7 @@ module ActiveSupport
|
|
685
708
|
end
|
686
709
|
|
687
710
|
def get_entry_value(entry, name, options)
|
688
|
-
instrument(:fetch_hit, name, options) {}
|
711
|
+
instrument(:fetch_hit, name, options) { }
|
689
712
|
entry.value
|
690
713
|
end
|
691
714
|
|
@@ -694,7 +717,7 @@ module ActiveSupport
|
|
694
717
|
yield(name)
|
695
718
|
end
|
696
719
|
|
697
|
-
write(name, result, options)
|
720
|
+
write(name, result, options) unless result.nil? && options[:skip_nil]
|
698
721
|
result
|
699
722
|
end
|
700
723
|
end
|
@@ -23,6 +23,9 @@ module ActiveSupport
|
|
23
23
|
# +ClassMethods.set_callback+), and run the installed callbacks at the
|
24
24
|
# appropriate times (via +run_callbacks+).
|
25
25
|
#
|
26
|
+
# By default callbacks are halted by throwing +:abort+.
|
27
|
+
# See +ClassMethods.define_callbacks+ for details.
|
28
|
+
#
|
26
29
|
# Three kinds of callbacks are supported: before callbacks, run before a
|
27
30
|
# certain event; after callbacks, run after the event; and around callbacks,
|
28
31
|
# blocks that surround the event, triggering it when they yield. Callback code
|
@@ -139,7 +142,6 @@ module ActiveSupport
|
|
139
142
|
end
|
140
143
|
|
141
144
|
private
|
142
|
-
|
143
145
|
# A hook invoked every time a before callback is halted.
|
144
146
|
# This can be overridden in ActiveSupport::Callbacks implementors in order
|
145
147
|
# to provide better debugging/logging.
|
@@ -497,9 +499,7 @@ module ActiveSupport
|
|
497
499
|
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
|
498
500
|
end
|
499
501
|
|
500
|
-
|
501
|
-
@nested
|
502
|
-
end
|
502
|
+
attr_reader :nested
|
503
503
|
|
504
504
|
def final?
|
505
505
|
!@call_template
|
@@ -578,10 +578,9 @@ module ActiveSupport
|
|
578
578
|
end
|
579
579
|
|
580
580
|
protected
|
581
|
-
|
581
|
+
attr_reader :chain
|
582
582
|
|
583
583
|
private
|
584
|
-
|
585
584
|
def append_one(callback)
|
586
585
|
@callbacks = nil
|
587
586
|
remove_duplicates(callback)
|
@@ -659,9 +658,17 @@ module ActiveSupport
|
|
659
658
|
# * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance
|
660
659
|
# method or a proc; the callback will be called only when they all return
|
661
660
|
# a true value.
|
661
|
+
#
|
662
|
+
# If a proc is given, its body is evaluated in the context of the
|
663
|
+
# current object. It can also optionally accept the current object as
|
664
|
+
# an argument.
|
662
665
|
# * <tt>:unless</tt> - A symbol or an array of symbols, each naming an
|
663
666
|
# instance method or a proc; the callback will be called only when they
|
664
667
|
# all return a false value.
|
668
|
+
#
|
669
|
+
# If a proc is given, its body is evaluated in the context of the
|
670
|
+
# current object. It can also optionally accept the current object as
|
671
|
+
# an argument.
|
665
672
|
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
|
666
673
|
# existing chain rather than appended.
|
667
674
|
def set_callback(name, *filter_list, &block)
|
@@ -809,7 +816,9 @@ module ActiveSupport
|
|
809
816
|
names.each do |name|
|
810
817
|
name = name.to_sym
|
811
818
|
|
812
|
-
|
819
|
+
([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
|
820
|
+
target.set_callbacks name, CallbackChain.new(name, options)
|
821
|
+
end
|
813
822
|
|
814
823
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
815
824
|
def _run_#{name}_callbacks(&block)
|
@@ -832,7 +841,6 @@ module ActiveSupport
|
|
832
841
|
end
|
833
842
|
|
834
843
|
protected
|
835
|
-
|
836
844
|
def get_callbacks(name) # :nodoc:
|
837
845
|
__callbacks[name.to_sym]
|
838
846
|
end
|
@@ -110,7 +110,7 @@ module ActiveSupport
|
|
110
110
|
base.instance_variable_set(:@_dependencies, [])
|
111
111
|
end
|
112
112
|
|
113
|
-
def append_features(base)
|
113
|
+
def append_features(base) #:nodoc:
|
114
114
|
if base.instance_variable_defined?(:@_dependencies)
|
115
115
|
base.instance_variable_get(:@_dependencies) << self
|
116
116
|
false
|
@@ -123,6 +123,9 @@ module ActiveSupport
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
# Evaluate given block in context of base class,
|
127
|
+
# so that you can write class macros here.
|
128
|
+
# When you define more than one +included+ block, it raises an exception.
|
126
129
|
def included(base = nil, &block)
|
127
130
|
if base.nil?
|
128
131
|
if instance_variable_defined?(:@_included_block)
|
@@ -137,6 +140,26 @@ module ActiveSupport
|
|
137
140
|
end
|
138
141
|
end
|
139
142
|
|
143
|
+
# Define class methods from given block.
|
144
|
+
# You can define private class methods as well.
|
145
|
+
#
|
146
|
+
# module Example
|
147
|
+
# extend ActiveSupport::Concern
|
148
|
+
#
|
149
|
+
# class_methods do
|
150
|
+
# def foo; puts 'foo'; end
|
151
|
+
#
|
152
|
+
# private
|
153
|
+
# def bar; puts 'bar'; end
|
154
|
+
# end
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# class Buzz
|
158
|
+
# include Example
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# Buzz.foo # => "foo"
|
162
|
+
# Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError)
|
140
163
|
def class_methods(&class_methods_module_definition)
|
141
164
|
mod = const_defined?(:ClassMethods, false) ?
|
142
165
|
const_get(:ClassMethods) :
|
@@ -7,11 +7,29 @@ module ActiveSupport
|
|
7
7
|
# A monitor that will permit dependency loading while blocked waiting for
|
8
8
|
# the lock.
|
9
9
|
class LoadInterlockAwareMonitor < Monitor
|
10
|
+
EXCEPTION_NEVER = { Exception => :never }.freeze
|
11
|
+
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
12
|
+
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
13
|
+
|
10
14
|
# Enters an exclusive section, but allows dependency loading while blocked
|
11
15
|
def mon_enter
|
12
16
|
mon_try_enter ||
|
13
17
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
|
14
18
|
end
|
19
|
+
|
20
|
+
def synchronize
|
21
|
+
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
22
|
+
mon_enter
|
23
|
+
|
24
|
+
begin
|
25
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
|
26
|
+
yield
|
27
|
+
end
|
28
|
+
ensure
|
29
|
+
mon_exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
15
33
|
end
|
16
34
|
end
|
17
35
|
end
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/concern"
|
4
4
|
require "active_support/ordered_options"
|
5
|
-
require "active_support/core_ext/array/extract_options"
|
6
|
-
require "active_support/core_ext/regexp"
|
7
5
|
|
8
6
|
module ActiveSupport
|
9
7
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
@@ -69,8 +67,8 @@ module ActiveSupport
|
|
69
67
|
# end
|
70
68
|
# # => NameError: invalid config attribute name
|
71
69
|
#
|
72
|
-
# To
|
73
|
-
# To
|
70
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
71
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
74
72
|
#
|
75
73
|
# class User
|
76
74
|
# include ActiveSupport::Configurable
|
@@ -83,7 +81,7 @@ module ActiveSupport
|
|
83
81
|
# User.new.allowed_access = true # => NoMethodError
|
84
82
|
# User.new.allowed_access # => NoMethodError
|
85
83
|
#
|
86
|
-
# Or pass <tt>instance_accessor: false</tt>, to
|
84
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
87
85
|
#
|
88
86
|
# class User
|
89
87
|
# include ActiveSupport::Configurable
|
@@ -106,9 +104,7 @@ module ActiveSupport
|
|
106
104
|
# end
|
107
105
|
#
|
108
106
|
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
109
|
-
def config_accessor(*names)
|
110
|
-
options = names.extract_options!
|
111
|
-
|
107
|
+
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
|
112
108
|
names.each do |name|
|
113
109
|
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
|
114
110
|
|
@@ -118,9 +114,9 @@ module ActiveSupport
|
|
118
114
|
singleton_class.class_eval reader, __FILE__, reader_line
|
119
115
|
singleton_class.class_eval writer, __FILE__, writer_line
|
120
116
|
|
121
|
-
|
122
|
-
class_eval reader, __FILE__, reader_line
|
123
|
-
class_eval writer, __FILE__, writer_line
|
117
|
+
if instance_accessor
|
118
|
+
class_eval reader, __FILE__, reader_line if instance_reader
|
119
|
+
class_eval writer, __FILE__, writer_line if instance_writer
|
124
120
|
end
|
125
121
|
send("#{name}=", yield) if block_given?
|
126
122
|
end
|