activesupport 7.1.6 → 7.2.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 +212 -1122
- data/README.rdoc +1 -1
- data/lib/active_support/array_inquirer.rb +1 -1
- data/lib/active_support/backtrace_cleaner.rb +10 -3
- data/lib/active_support/broadcast_logger.rb +65 -78
- data/lib/active_support/cache/file_store.rb +17 -12
- data/lib/active_support/cache/mem_cache_store.rb +29 -89
- data/lib/active_support/cache/memory_store.rb +7 -6
- data/lib/active_support/cache/null_store.rb +2 -2
- data/lib/active_support/cache/redis_cache_store.rb +17 -14
- data/lib/active_support/cache/serializer_with_fallback.rb +0 -23
- data/lib/active_support/cache/strategy/local_cache.rb +56 -20
- data/lib/active_support/cache.rb +63 -71
- data/lib/active_support/callbacks.rb +77 -115
- data/lib/active_support/core_ext/array/conversions.rb +0 -2
- data/lib/active_support/core_ext/benchmark.rb +1 -0
- data/lib/active_support/core_ext/class/attribute.rb +2 -1
- data/lib/active_support/core_ext/class/subclasses.rb +15 -35
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/conversions.rb +0 -2
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +4 -6
- data/lib/active_support/core_ext/digest/uuid.rb +6 -0
- data/lib/active_support/core_ext/enumerable.rb +17 -5
- data/lib/active_support/core_ext/erb/util.rb +7 -2
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -163
- data/lib/active_support/core_ext/module/deprecation.rb +1 -4
- data/lib/active_support/core_ext/module/introspection.rb +3 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +3 -3
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +11 -19
- data/lib/active_support/core_ext/object/json.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object/with.rb +5 -3
- data/lib/active_support/core_ext/pathname/blank.rb +4 -0
- data/lib/active_support/core_ext/range/overlap.rb +1 -1
- 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/securerandom.rb +4 -4
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +4 -4
- data/lib/active_support/core_ext/string/multibyte.rb +3 -3
- data/lib/active_support/core_ext/string/output_safety.rb +0 -7
- data/lib/active_support/core_ext/time/calculations.rb +18 -28
- data/lib/active_support/core_ext/time/compatibility.rb +24 -0
- data/lib/active_support/core_ext/time/conversions.rb +0 -2
- data/lib/active_support/core_ext/time/zones.rb +1 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +45 -40
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +0 -12
- data/lib/active_support/deprecation/constant_accessor.rb +47 -26
- data/lib/active_support/deprecation/proxy_wrappers.rb +9 -12
- data/lib/active_support/deprecation/reporting.rb +7 -2
- data/lib/active_support/deprecation.rb +8 -5
- data/lib/active_support/descendants_tracker.rb +9 -87
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -2
- data/lib/active_support/duration.rb +11 -6
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/error_reporter.rb +46 -5
- data/lib/active_support/evented_file_update_checker.rb +0 -1
- data/lib/active_support/execution_wrapper.rb +1 -2
- data/lib/active_support/file_update_checker.rb +2 -2
- data/lib/active_support/fork_tracker.rb +2 -38
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +26 -24
- data/lib/active_support/html_safe_translation.rb +3 -0
- data/lib/active_support/json/decoding.rb +1 -1
- data/lib/active_support/json/encoding.rb +23 -5
- data/lib/active_support/lazy_load_hooks.rb +1 -1
- data/lib/active_support/log_subscriber.rb +0 -12
- data/lib/active_support/logger.rb +15 -2
- data/lib/active_support/logger_thread_safe_level.rb +0 -8
- data/lib/active_support/message_encryptors.rb +2 -2
- data/lib/active_support/message_pack/extensions.rb +15 -2
- data/lib/active_support/message_verifier.rb +21 -0
- data/lib/active_support/message_verifiers.rb +5 -3
- data/lib/active_support/messages/rotator.rb +5 -0
- data/lib/active_support/multibyte/chars.rb +6 -3
- data/lib/active_support/notifications/fanout.rb +4 -7
- data/lib/active_support/notifications/instrumenter.rb +21 -18
- data/lib/active_support/notifications.rb +28 -27
- data/lib/active_support/number_helper/number_converter.rb +2 -2
- data/lib/active_support/option_merger.rb +2 -2
- data/lib/active_support/ordered_options.rb +53 -15
- data/lib/active_support/proxy_object.rb +8 -5
- data/lib/active_support/railtie.rb +4 -11
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +1 -0
- data/lib/active_support/tagged_logging.rb +0 -1
- data/lib/active_support/test_case.rb +3 -1
- data/lib/active_support/testing/assertions.rb +4 -4
- data/lib/active_support/testing/constant_stubbing.rb +30 -8
- data/lib/active_support/testing/deprecation.rb +5 -12
- data/lib/active_support/testing/isolation.rb +20 -8
- data/lib/active_support/testing/method_call_assertions.rb +2 -16
- data/lib/active_support/testing/parallelization/server.rb +18 -2
- data/lib/active_support/testing/parallelization/worker.rb +2 -2
- data/lib/active_support/testing/parallelization.rb +12 -1
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +3 -3
- data/lib/active_support/time_with_zone.rb +8 -4
- data/lib/active_support/values/time_zone.rb +7 -7
- data/lib/active_support/xml_mini.rb +13 -2
- data/lib/active_support.rb +2 -1
- metadata +16 -24
- data/lib/active_support/deprecation/instance_delegator.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
- data/lib/active_support/testing/strict_warnings.rb +0 -39
|
@@ -150,7 +150,7 @@ module ActiveSupport
|
|
|
150
150
|
def halted_callback_hook(filter, name)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
module Conditionals # :nodoc:
|
|
153
|
+
module Conditionals # :nodoc: all
|
|
154
154
|
class Value
|
|
155
155
|
def initialize(&block)
|
|
156
156
|
@block = block
|
|
@@ -159,128 +159,76 @@ module ActiveSupport
|
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
|
|
162
|
-
module Filters
|
|
162
|
+
module Filters # :nodoc: all
|
|
163
163
|
Environment = Struct.new(:target, :halted, :value)
|
|
164
164
|
|
|
165
165
|
class Before
|
|
166
|
-
def
|
|
166
|
+
def initialize(user_callback, user_conditions, chain_config, filter, name)
|
|
167
167
|
halted_lambda = chain_config[:terminator]
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
|
171
|
-
else
|
|
172
|
-
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
|
173
|
-
end
|
|
168
|
+
@user_callback, @user_conditions, @halted_lambda, @filter, @name = user_callback, user_conditions, halted_lambda, filter, name
|
|
169
|
+
freeze
|
|
174
170
|
end
|
|
171
|
+
attr_reader :user_callback, :user_conditions, :halted_lambda, :filter, :name
|
|
175
172
|
|
|
176
|
-
def
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
halted = env.halted
|
|
173
|
+
def call(env)
|
|
174
|
+
target = env.target
|
|
175
|
+
value = env.value
|
|
176
|
+
halted = env.halted
|
|
181
177
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
178
|
+
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
|
179
|
+
result_lambda = -> { user_callback.call target, value }
|
|
180
|
+
env.halted = halted_lambda.call(target, result_lambda)
|
|
181
|
+
if env.halted
|
|
182
|
+
target.send :halted_callback_hook, filter, name
|
|
188
183
|
end
|
|
189
|
-
|
|
190
|
-
env
|
|
191
184
|
end
|
|
192
|
-
end
|
|
193
|
-
private_class_method :halting_and_conditional
|
|
194
|
-
|
|
195
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
|
196
|
-
callback_sequence.before do |env|
|
|
197
|
-
target = env.target
|
|
198
|
-
value = env.value
|
|
199
|
-
halted = env.halted
|
|
200
185
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
env.halted = halted_lambda.call(target, result_lambda)
|
|
204
|
-
if env.halted
|
|
205
|
-
target.send :halted_callback_hook, filter, name
|
|
206
|
-
end
|
|
207
|
-
end
|
|
186
|
+
env
|
|
187
|
+
end
|
|
208
188
|
|
|
209
|
-
|
|
210
|
-
|
|
189
|
+
def apply(callback_sequence)
|
|
190
|
+
callback_sequence.before(self)
|
|
211
191
|
end
|
|
212
|
-
private_class_method :halting
|
|
213
192
|
end
|
|
214
193
|
|
|
215
194
|
class After
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
halting(callback_sequence, user_callback)
|
|
222
|
-
end
|
|
223
|
-
else
|
|
224
|
-
if user_conditions.any?
|
|
225
|
-
conditional callback_sequence, user_callback, user_conditions
|
|
226
|
-
else
|
|
227
|
-
simple callback_sequence, user_callback
|
|
228
|
-
end
|
|
229
|
-
end
|
|
195
|
+
attr_reader :user_callback, :user_conditions, :halting
|
|
196
|
+
def initialize(user_callback, user_conditions, chain_config)
|
|
197
|
+
halting = chain_config[:skip_after_callbacks_if_terminated]
|
|
198
|
+
@user_callback, @user_conditions, @halting = user_callback, user_conditions, halting
|
|
199
|
+
freeze
|
|
230
200
|
end
|
|
231
201
|
|
|
232
|
-
def
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
halted = env.halted
|
|
237
|
-
|
|
238
|
-
if !halted && user_conditions.all? { |c| c.call(target, value) }
|
|
239
|
-
user_callback.call target, value
|
|
240
|
-
end
|
|
202
|
+
def call(env)
|
|
203
|
+
target = env.target
|
|
204
|
+
value = env.value
|
|
205
|
+
halted = env.halted
|
|
241
206
|
|
|
242
|
-
|
|
207
|
+
if (!halted || !@halting) && user_conditions.all? { |c| c.call(target, value) }
|
|
208
|
+
user_callback.call target, value
|
|
243
209
|
end
|
|
244
|
-
end
|
|
245
|
-
private_class_method :halting_and_conditional
|
|
246
|
-
|
|
247
|
-
def self.halting(callback_sequence, user_callback)
|
|
248
|
-
callback_sequence.after do |env|
|
|
249
|
-
unless env.halted
|
|
250
|
-
user_callback.call env.target, env.value
|
|
251
|
-
end
|
|
252
210
|
|
|
253
|
-
|
|
254
|
-
end
|
|
211
|
+
env
|
|
255
212
|
end
|
|
256
|
-
private_class_method :halting
|
|
257
|
-
|
|
258
|
-
def self.conditional(callback_sequence, user_callback, user_conditions)
|
|
259
|
-
callback_sequence.after do |env|
|
|
260
|
-
target = env.target
|
|
261
|
-
value = env.value
|
|
262
213
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
env
|
|
268
|
-
end
|
|
214
|
+
def apply(callback_sequence)
|
|
215
|
+
callback_sequence.after(self)
|
|
269
216
|
end
|
|
270
|
-
|
|
217
|
+
end
|
|
271
218
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
219
|
+
class Around
|
|
220
|
+
def initialize(user_callback, user_conditions)
|
|
221
|
+
@user_callback, @user_conditions = user_callback, user_conditions
|
|
222
|
+
freeze
|
|
223
|
+
end
|
|
275
224
|
|
|
276
|
-
|
|
277
|
-
|
|
225
|
+
def apply(callback_sequence)
|
|
226
|
+
callback_sequence.around(@user_callback, @user_conditions)
|
|
278
227
|
end
|
|
279
|
-
private_class_method :simple
|
|
280
228
|
end
|
|
281
229
|
end
|
|
282
230
|
|
|
283
|
-
class Callback # :nodoc
|
|
231
|
+
class Callback # :nodoc:
|
|
284
232
|
def self.build(chain, filter, kind, options)
|
|
285
233
|
if filter.is_a?(String)
|
|
286
234
|
raise ArgumentError, <<-MSG.squish
|
|
@@ -302,6 +250,8 @@ module ActiveSupport
|
|
|
302
250
|
@filter = filter
|
|
303
251
|
@if = check_conditionals(options[:if])
|
|
304
252
|
@unless = check_conditionals(options[:unless])
|
|
253
|
+
|
|
254
|
+
compiled
|
|
305
255
|
end
|
|
306
256
|
|
|
307
257
|
def merge_conditional_options(chain, if_option:, unless_option:)
|
|
@@ -329,19 +279,26 @@ module ActiveSupport
|
|
|
329
279
|
end
|
|
330
280
|
end
|
|
331
281
|
|
|
282
|
+
def compiled
|
|
283
|
+
@compiled ||=
|
|
284
|
+
begin
|
|
285
|
+
user_conditions = conditions_lambdas
|
|
286
|
+
user_callback = CallTemplate.build(@filter, self)
|
|
287
|
+
|
|
288
|
+
case kind
|
|
289
|
+
when :before
|
|
290
|
+
Filters::Before.new(user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
|
291
|
+
when :after
|
|
292
|
+
Filters::After.new(user_callback.make_lambda, user_conditions, chain_config)
|
|
293
|
+
when :around
|
|
294
|
+
Filters::Around.new(user_callback, user_conditions)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
332
299
|
# Wraps code with filter
|
|
333
300
|
def apply(callback_sequence)
|
|
334
|
-
|
|
335
|
-
user_callback = CallTemplate.build(@filter, self)
|
|
336
|
-
|
|
337
|
-
case kind
|
|
338
|
-
when :before
|
|
339
|
-
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
|
340
|
-
when :after
|
|
341
|
-
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
|
342
|
-
when :around
|
|
343
|
-
callback_sequence.around(user_callback, user_conditions)
|
|
344
|
-
end
|
|
301
|
+
compiled.apply(callback_sequence)
|
|
345
302
|
end
|
|
346
303
|
|
|
347
304
|
def current_scopes
|
|
@@ -368,14 +325,16 @@ module ActiveSupport
|
|
|
368
325
|
end
|
|
369
326
|
|
|
370
327
|
def conditions_lambdas
|
|
371
|
-
|
|
328
|
+
conditions =
|
|
329
|
+
@if.map { |c| CallTemplate.build(c, self).make_lambda } +
|
|
372
330
|
@unless.map { |c| CallTemplate.build(c, self).inverted_lambda }
|
|
331
|
+
conditions.empty? ? EMPTY_ARRAY : conditions
|
|
373
332
|
end
|
|
374
333
|
end
|
|
375
334
|
|
|
376
335
|
# A future invocation of user-supplied code (either as a callback,
|
|
377
336
|
# or a condition filter).
|
|
378
|
-
module CallTemplate # :nodoc:
|
|
337
|
+
module CallTemplate # :nodoc: all
|
|
379
338
|
class MethodCall
|
|
380
339
|
def initialize(method)
|
|
381
340
|
@method_name = method
|
|
@@ -540,9 +499,10 @@ module ActiveSupport
|
|
|
540
499
|
when Conditionals::Value
|
|
541
500
|
ProcCall.new(filter)
|
|
542
501
|
when ::Proc
|
|
543
|
-
|
|
502
|
+
case filter.arity
|
|
503
|
+
when 2
|
|
544
504
|
InstanceExec2.new(filter)
|
|
545
|
-
|
|
505
|
+
when 1, -2
|
|
546
506
|
InstanceExec1.new(filter)
|
|
547
507
|
else
|
|
548
508
|
InstanceExec0.new(filter)
|
|
@@ -562,16 +522,18 @@ module ActiveSupport
|
|
|
562
522
|
@call_template = call_template
|
|
563
523
|
@user_conditions = user_conditions
|
|
564
524
|
|
|
565
|
-
@before =
|
|
566
|
-
@after =
|
|
525
|
+
@before = nil
|
|
526
|
+
@after = nil
|
|
567
527
|
end
|
|
568
528
|
|
|
569
|
-
def before(
|
|
529
|
+
def before(before)
|
|
530
|
+
@before ||= []
|
|
570
531
|
@before.unshift(before)
|
|
571
532
|
self
|
|
572
533
|
end
|
|
573
534
|
|
|
574
|
-
def after(
|
|
535
|
+
def after(after)
|
|
536
|
+
@after ||= []
|
|
575
537
|
@after.push(after)
|
|
576
538
|
self
|
|
577
539
|
end
|
|
@@ -595,11 +557,11 @@ module ActiveSupport
|
|
|
595
557
|
end
|
|
596
558
|
|
|
597
559
|
def invoke_before(arg)
|
|
598
|
-
@before
|
|
560
|
+
@before&.each { |b| b.call(arg) }
|
|
599
561
|
end
|
|
600
562
|
|
|
601
563
|
def invoke_after(arg)
|
|
602
|
-
@after
|
|
564
|
+
@after&.each { |a| a.call(arg) }
|
|
603
565
|
end
|
|
604
566
|
end
|
|
605
567
|
|
|
@@ -104,8 +104,6 @@ class Array
|
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
alias_method :to_formatted_s, :to_fs
|
|
107
|
-
alias_method :to_default_s, :to_s
|
|
108
|
-
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
|
109
107
|
|
|
110
108
|
# Returns a string that represents the array in XML by invoking +to_xml+
|
|
111
109
|
# on each element. Active Record collections delegate their representation
|
|
@@ -83,7 +83,8 @@ class Class
|
|
|
83
83
|
#
|
|
84
84
|
# class_attribute :settings, default: {}
|
|
85
85
|
def class_attribute(*attrs, instance_accessor: true,
|
|
86
|
-
instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil
|
|
86
|
+
instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil
|
|
87
|
+
)
|
|
87
88
|
class_methods, methods = [], []
|
|
88
89
|
attrs.each do |name|
|
|
89
90
|
unless name.is_a?(Symbol) || name.is_a?(String)
|
|
@@ -1,43 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_support/ruby_features"
|
|
4
3
|
require "active_support/descendants_tracker"
|
|
5
4
|
|
|
6
5
|
class Class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
subclasses.concat(subclasses.flat_map(&:descendants))
|
|
23
|
-
end
|
|
24
|
-
else
|
|
25
|
-
def descendants
|
|
26
|
-
ObjectSpace.each_object(singleton_class).reject do |k|
|
|
27
|
-
k.singleton_class? || k == self
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Returns an array with the direct children of +self+.
|
|
32
|
-
#
|
|
33
|
-
# class Foo; end
|
|
34
|
-
# class Bar < Foo; end
|
|
35
|
-
# class Baz < Bar; end
|
|
36
|
-
#
|
|
37
|
-
# Foo.subclasses # => [Bar]
|
|
38
|
-
def subclasses
|
|
39
|
-
descendants.select { |descendant| descendant.superclass == self }
|
|
40
|
-
end
|
|
6
|
+
# Returns an array with all classes that are < than its receiver.
|
|
7
|
+
#
|
|
8
|
+
# class C; end
|
|
9
|
+
# C.descendants # => []
|
|
10
|
+
#
|
|
11
|
+
# class B < C; end
|
|
12
|
+
# C.descendants # => [B]
|
|
13
|
+
#
|
|
14
|
+
# class A < B; end
|
|
15
|
+
# C.descendants # => [B, A]
|
|
16
|
+
#
|
|
17
|
+
# class D < C; end
|
|
18
|
+
# C.descendants # => [B, A, D]
|
|
19
|
+
def descendants
|
|
20
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
|
41
21
|
end
|
|
42
22
|
|
|
43
23
|
prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
|
|
@@ -56,8 +56,6 @@ class Date
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
alias_method :to_formatted_s, :to_fs
|
|
59
|
-
alias_method :to_default_s, :to_s
|
|
60
|
-
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
|
61
59
|
|
|
62
60
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
|
63
61
|
def readable_inspect
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/module/attribute_accessors"
|
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
|
4
5
|
|
|
5
6
|
module DateAndTime
|
|
6
7
|
module Compatibility
|
|
@@ -11,7 +12,33 @@ module DateAndTime
|
|
|
11
12
|
# of the receiver. For backwards compatibility we're overriding
|
|
12
13
|
# this behavior, but new apps will have an initializer that sets
|
|
13
14
|
# this to true, because the new behavior is preferred.
|
|
14
|
-
mattr_accessor :preserve_timezone,
|
|
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 timezone offset of the receiver in Rails 8.0. " \
|
|
30
|
+
"To opt in to the new behavior, set `ActiveSupport.to_time_preserves_timezone = true`."
|
|
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
|
|
15
42
|
|
|
16
43
|
# Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
|
|
17
44
|
#
|
|
@@ -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
|
|
@@ -40,10 +42,6 @@ class DateTime
|
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
alias_method :to_formatted_s, :to_fs
|
|
43
|
-
if instance_methods(false).include?(:to_s)
|
|
44
|
-
alias_method :to_default_s, :to_s
|
|
45
|
-
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
|
46
|
-
end
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
# Returns a formatted string of the offset from UTC, or an alternative
|
|
@@ -53,6 +53,12 @@ module Digest
|
|
|
53
53
|
SecureRandom.uuid
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# Returns the nil UUID. This is a special form of UUID that is specified to
|
|
57
|
+
# have all 128 bits set to zero.
|
|
58
|
+
def self.nil_uuid
|
|
59
|
+
"00000000-0000-0000-0000-000000000000"
|
|
60
|
+
end
|
|
61
|
+
|
|
56
62
|
def self.pack_uuid_namespace(namespace)
|
|
57
63
|
if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace)
|
|
58
64
|
namespace
|
|
@@ -198,16 +198,28 @@ module Enumerable
|
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
# Returns the sole item in the enumerable. If there are no items, or more
|
|
201
|
-
# than one item, raises
|
|
201
|
+
# than one item, raises Enumerable::SoleItemExpectedError.
|
|
202
202
|
#
|
|
203
203
|
# ["x"].sole # => "x"
|
|
204
204
|
# Set.new.sole # => Enumerable::SoleItemExpectedError: no item found
|
|
205
205
|
# { a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
|
|
206
206
|
def sole
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
result = nil
|
|
208
|
+
found = false
|
|
209
|
+
|
|
210
|
+
each do |*element|
|
|
211
|
+
if found
|
|
212
|
+
raise SoleItemExpectedError, "multiple items found"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
result = element.size == 1 ? element[0] : element
|
|
216
|
+
found = true
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
if found
|
|
220
|
+
result
|
|
221
|
+
else
|
|
222
|
+
raise SoleItemExpectedError, "no item found"
|
|
211
223
|
end
|
|
212
224
|
end
|
|
213
225
|
end
|
|
@@ -174,7 +174,7 @@ class ERB
|
|
|
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,11 +183,16 @@ 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
|
|
190
190
|
end
|
|
191
|
+
|
|
192
|
+
unless source.eos? || source.exist?(start_re) || source.exist?(finish_re)
|
|
193
|
+
tokens << [:TEXT, source.rest]
|
|
194
|
+
source.terminate
|
|
195
|
+
end
|
|
191
196
|
end
|
|
192
197
|
|
|
193
198
|
tokens
|
|
@@ -8,13 +8,13 @@ class Hash
|
|
|
8
8
|
# hash.stringify_keys
|
|
9
9
|
# # => {"name"=>"Rob", "age"=>"28"}
|
|
10
10
|
def stringify_keys
|
|
11
|
-
transform_keys
|
|
11
|
+
transform_keys { |k| Symbol === k ? k.name : k.to_s }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Destructively converts all keys to strings. Same as
|
|
15
15
|
# +stringify_keys+, but modifies +self+.
|
|
16
16
|
def stringify_keys!
|
|
17
|
-
transform_keys!
|
|
17
|
+
transform_keys! { |k| Symbol === k ? k.name : k.to_s }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Returns a new hash with all keys converted to symbols, as long as
|
|
@@ -82,14 +82,14 @@ class Hash
|
|
|
82
82
|
# hash.deep_stringify_keys
|
|
83
83
|
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
|
84
84
|
def deep_stringify_keys
|
|
85
|
-
deep_transform_keys
|
|
85
|
+
deep_transform_keys { |k| Symbol === k ? k.name : k.to_s }
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
# Destructively converts all keys to strings.
|
|
89
89
|
# This includes the keys from the root hash and from all
|
|
90
90
|
# nested hashes and arrays.
|
|
91
91
|
def deep_stringify_keys!
|
|
92
|
-
deep_transform_keys!
|
|
92
|
+
deep_transform_keys! { |k| Symbol === k ? k.name : k.to_s }
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
# Returns a new hash with all keys converted to symbols, as long as
|
|
@@ -19,16 +19,27 @@ class Module
|
|
|
19
19
|
end
|
|
20
20
|
alias_method :attr_internal, :attr_internal_accessor
|
|
21
21
|
|
|
22
|
-
class << self
|
|
23
|
-
|
|
22
|
+
class << self
|
|
23
|
+
attr_reader :attr_internal_naming_format
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def attr_internal_naming_format=(format)
|
|
26
|
+
if format.start_with?("@")
|
|
27
|
+
ActiveSupport.deprecator.warn <<~MESSAGE
|
|
28
|
+
Setting `attr_internal_naming_format` with a `@` prefix is deprecated and will be removed in Rails 8.0.
|
|
29
|
+
|
|
30
|
+
You can simply replace #{format.inspect} by #{format.delete_prefix("@").inspect}.
|
|
31
|
+
MESSAGE
|
|
32
|
+
|
|
33
|
+
format = format.delete_prefix("@")
|
|
34
|
+
end
|
|
35
|
+
@attr_internal_naming_format = format
|
|
28
36
|
end
|
|
37
|
+
end
|
|
38
|
+
self.attr_internal_naming_format = "_%s"
|
|
29
39
|
|
|
40
|
+
private
|
|
30
41
|
def attr_internal_define(attr_name, type)
|
|
31
|
-
internal_name =
|
|
42
|
+
internal_name = Module.attr_internal_naming_format % attr_name
|
|
32
43
|
# use native attr_* methods as they are faster on some Ruby implementations
|
|
33
44
|
public_send("attr_#{type}", internal_name)
|
|
34
45
|
attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
|