activesupport 7.0.0.alpha2 → 7.0.0.rc1

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.

Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +80 -0
  3. data/lib/active_support/cache/mem_cache_store.rb +9 -5
  4. data/lib/active_support/cache/memory_store.rb +2 -2
  5. data/lib/active_support/cache/redis_cache_store.rb +3 -8
  6. data/lib/active_support/cache/strategy/local_cache.rb +6 -12
  7. data/lib/active_support/callbacks.rb +145 -50
  8. data/lib/active_support/code_generator.rb +65 -0
  9. data/lib/active_support/core_ext/array/conversions.rb +3 -1
  10. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  11. data/lib/active_support/core_ext/array.rb +1 -0
  12. data/lib/active_support/core_ext/class/subclasses.rb +4 -2
  13. data/lib/active_support/core_ext/date/calculations.rb +2 -2
  14. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  15. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  16. data/lib/active_support/core_ext/date.rb +1 -0
  17. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  18. data/lib/active_support/core_ext/date_time/conversions.rb +5 -5
  19. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  20. data/lib/active_support/core_ext/date_time.rb +1 -0
  21. data/lib/active_support/core_ext/digest/uuid.rb +26 -1
  22. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  23. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  24. data/lib/active_support/core_ext/numeric/conversions.rb +78 -75
  25. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  26. data/lib/active_support/core_ext/numeric.rb +1 -0
  27. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  28. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  29. data/lib/active_support/core_ext/pathname.rb +3 -0
  30. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  31. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  32. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  33. data/lib/active_support/core_ext/range.rb +1 -1
  34. data/lib/active_support/core_ext/time/calculations.rb +1 -1
  35. data/lib/active_support/core_ext/time/conversions.rb +4 -3
  36. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  37. data/lib/active_support/core_ext/time/zones.rb +2 -2
  38. data/lib/active_support/core_ext/time.rb +1 -0
  39. data/lib/active_support/core_ext/uri.rb +3 -13
  40. data/lib/active_support/core_ext.rb +1 -0
  41. data/lib/active_support/current_attributes.rb +26 -25
  42. data/lib/active_support/descendants_tracker.rb +175 -69
  43. data/lib/active_support/error_reporter.rb +117 -0
  44. data/lib/active_support/execution_context/test_helper.rb +13 -0
  45. data/lib/active_support/execution_context.rb +53 -0
  46. data/lib/active_support/execution_wrapper.rb +30 -4
  47. data/lib/active_support/executor/test_helper.rb +7 -0
  48. data/lib/active_support/fork_tracker.rb +18 -9
  49. data/lib/active_support/gem_version.rb +1 -1
  50. data/lib/active_support/html_safe_translation.rb +43 -0
  51. data/lib/active_support/i18n_railtie.rb +1 -1
  52. data/lib/active_support/inflector/inflections.rb +12 -3
  53. data/lib/active_support/inflector/methods.rb +2 -2
  54. data/lib/active_support/isolated_execution_state.rb +56 -0
  55. data/lib/active_support/logger_thread_safe_level.rb +2 -3
  56. data/lib/active_support/message_encryptor.rb +5 -0
  57. data/lib/active_support/multibyte/unicode.rb +0 -12
  58. data/lib/active_support/notifications/fanout.rb +61 -55
  59. data/lib/active_support/notifications/instrumenter.rb +15 -15
  60. data/lib/active_support/notifications.rb +5 -21
  61. data/lib/active_support/option_merger.rb +4 -0
  62. data/lib/active_support/per_thread_registry.rb +4 -0
  63. data/lib/active_support/railtie.rb +38 -11
  64. data/lib/active_support/ruby_features.rb +7 -0
  65. data/lib/active_support/subscriber.rb +2 -18
  66. data/lib/active_support/tagged_logging.rb +1 -1
  67. data/lib/active_support/testing/deprecation.rb +52 -1
  68. data/lib/active_support/testing/isolation.rb +1 -1
  69. data/lib/active_support/time_with_zone.rb +34 -6
  70. data/lib/active_support/values/time_zone.rb +5 -0
  71. data/lib/active_support/xml_mini.rb +3 -3
  72. data/lib/active_support.rb +7 -4
  73. metadata +23 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5519479cbadbd2a19e3eaf56b8f1446903f303901f28fcf3b0d7b54f65105b00
4
- data.tar.gz: 3a69b60b6b587c44b8dfd6988bf0582a8bb872c888aa06dd318b63aba4532a62
3
+ metadata.gz: fc2a50831138a53abf91816c46a1ada54c6457c2a6be685e46c32fdacae8706d
4
+ data.tar.gz: 805b7df2562018d4991b711eda5badd29778b262cf82467f2d18c57bd69f8d2c
5
5
  SHA512:
6
- metadata.gz: ee3c9d43bd65e15a1b828ed60e2a6f4dd5734a2aad2d3aa7023def780f5148f6060d8ea4fff238f63a71b69c04b9b3ee6e5ba0671561c40118883b9ac7f2745d
7
- data.tar.gz: 2254965d4be1e85d7c37bb907e2f68e0323efbdb3ccac496eaec3d07d4f94cfc54dd1e090b2d7d6fd4a32e468bfdbb4c6dbe431d6b04959cb7efd7071a565cc6
6
+ metadata.gz: fc5e281a4b9549b92170e17056b0bb12911327b839d7af8d021ef8173e7432deceea44a1444a2c954f489ce534ea0bce527add775be03298d3d3f8224ba0e2af
7
+ data.tar.gz: fa401cf383e3bb17d03ae007d972b8f3b15f5b4565c05af3ee48895e60154a8c58e010096bfc50eb11a658102d1afbbad0d80b90744424783614d9146780b46b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,83 @@
1
+ * Deprecate passing a format to `#to_s` in favor of `#to_formatted_s` in `Array`, `Range`, `Date`, `DateTime`, `Time`,
2
+ `BigDecimal`, `Float` and, `Integer`.
3
+
4
+ *Rafael Mendonça França*
5
+
6
+ * Document `ActiveSupport::Testing::Deprecation`.
7
+
8
+ *Sam Bostock & Sam Jordan*
9
+
10
+ * Add `Pathname#existence`.
11
+
12
+ ```ruby
13
+ Pathname.new("file").existence&.read
14
+ ```
15
+
16
+ *Timo Schilling*
17
+
18
+ * Remove deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
19
+
20
+ *Rafael Mendonça França*
21
+
22
+ * Remove deprecated support to use `Range#include?` to check the inclusion of a value in
23
+ a date time range is deprecated.
24
+
25
+ *Rafael Mendonça França*
26
+
27
+ * Remove deprecated `URI.parser`.
28
+
29
+ *Rafael Mendonça França*
30
+
31
+ * Remove deprecated `config.active_support.use_sha1_digests`.
32
+
33
+ *Rafael Mendonça França*
34
+
35
+ * Invoking `Object#with_options` without a `&block` argument returns the
36
+ `ActiveSupport::OptionMerger` instance.
37
+
38
+ *Sean Doyle*
39
+
40
+ * `Rails.application.executor` hooks can now be called around every test
41
+
42
+ This helps to better simulate request or job local state being reset around tests and prevents state
43
+ leaking from one test to another.
44
+
45
+ However it requires the executor hooks executed in the test environment to be re-entrant.
46
+
47
+ To enable this, set `config.active_support.executor_around_test_case = true` (this is the default in Rails 7).
48
+
49
+ *Jean Boussier*
50
+
51
+ * `ActiveSupport::DescendantsTracker` now mostly delegate to `Class#descendants` on Ruby 3.1
52
+
53
+ Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless.
54
+
55
+ As a result the following methods are deprecated:
56
+
57
+ - `ActiveSupport::DescendantsTracker.direct_descendants`
58
+ - `ActiveSupport::DescendantsTracker#direct_descendants`
59
+
60
+ *Jean Boussier*
61
+
62
+ * Fix the `Digest::UUID.uuid_from_hash` behavior for namespace IDs that are different from the ones defined on `Digest::UUID`.
63
+
64
+ The new behavior will be enabled by setting the
65
+ `config.active_support.use_rfc4122_namespaced_uuids` option to `true`
66
+ and is the default for new apps.
67
+
68
+ The old behavior is the default for upgraded apps and will output a
69
+ deprecation warning every time a value that is different than one of
70
+ the constants defined on the `Digest::UUID` extension is used as the
71
+ namespace ID.
72
+
73
+ *Alex Robbin*, *Erich Soares Machado*, *Eugene Kenny*
74
+
75
+ * `ActiveSupport::Inflector::Inflections#clear(:acronyms)` is now supported,
76
+ and `inflector.clear` / `inflector.clear(:all)` also clears acronyms.
77
+
78
+ *Alex Ghiculescu*, *Oliver Peate*
79
+
80
+
1
81
  ## Rails 7.0.0.alpha2 (September 15, 2021) ##
2
82
 
3
83
  * No changes.
@@ -121,7 +121,9 @@ module ActiveSupport
121
121
  @data = addresses.first
122
122
  else
123
123
  mem_cache_options = options.dup
124
- UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
124
+ # The value "compress: false" prevents duplicate compression within Dalli.
125
+ mem_cache_options[:compress] = false
126
+ (UNIVERSAL_OPTIONS - %i(compress)).each { |name| mem_cache_options.delete(name) }
125
127
  @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
126
128
  end
127
129
  end
@@ -236,8 +238,9 @@ module ActiveSupport
236
238
  expires_in += 5.minutes
237
239
  end
238
240
  rescue_error_with false do
239
- # The value "compress: false" prevents duplicate compression within Dalli.
240
- @data.with { |c| c.send(method, key, payload, expires_in, **options, compress: false) }
241
+ # Don't pass compress option to Dalli since we are already dealing with compression.
242
+ options.delete(:compress)
243
+ @data.with { |c| c.send(method, key, payload, expires_in, **options) }
241
244
  end
242
245
  end
243
246
 
@@ -295,8 +298,9 @@ module ActiveSupport
295
298
 
296
299
  def rescue_error_with(fallback)
297
300
  yield
298
- rescue Dalli::DalliError => e
299
- logger.error("DalliError (#{e}): #{e.message}") if logger
301
+ rescue Dalli::DalliError => error
302
+ ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning)
303
+ logger.error("DalliError (#{error}): #{error.message}") if logger
300
304
  fallback
301
305
  end
302
306
  end
@@ -89,13 +89,13 @@ module ActiveSupport
89
89
  return if pruning?
90
90
  @pruning = true
91
91
  begin
92
- start_time = Concurrent.monotonic_time
92
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
93
93
  cleanup
94
94
  instrument(:prune, target_size, from: @cache_size) do
95
95
  keys = synchronize { @data.keys }
96
96
  keys.each do |key|
97
97
  delete_entry(key, **options)
98
- return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
98
+ return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time)
99
99
  end
100
100
  end
101
101
  ensure
@@ -458,16 +458,11 @@ module ActiveSupport
458
458
 
459
459
  def failsafe(method, returning: nil)
460
460
  yield
461
- rescue ::Redis::BaseError => e
462
- handle_exception exception: e, method: method, returning: returning
461
+ rescue ::Redis::BaseError => error
462
+ ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning)
463
+ @error_handler&.call(method: method, exception: error, returning: returning)
463
464
  returning
464
465
  end
465
-
466
- def handle_exception(exception:, method:, returning:)
467
- if @error_handler
468
- @error_handler.(method: method, exception: exception, returning: returning)
469
- end
470
- end
471
466
  end
472
467
  end
473
468
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/string/inflections"
4
- require "active_support/per_thread_registry"
5
4
 
6
5
  module ActiveSupport
7
6
  module Cache
@@ -13,23 +12,18 @@ module ActiveSupport
13
12
  autoload :Middleware, "active_support/cache/strategy/local_cache_middleware"
14
13
 
15
14
  # Class for storing and registering the local caches.
16
- class LocalCacheRegistry # :nodoc:
17
- extend ActiveSupport::PerThreadRegistry
18
-
19
- def initialize
20
- @registry = {}
21
- end
15
+ module LocalCacheRegistry # :nodoc:
16
+ extend self
22
17
 
23
18
  def cache_for(local_cache_key)
24
- @registry[local_cache_key]
19
+ registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
20
+ registry[local_cache_key]
25
21
  end
26
22
 
27
23
  def set_cache_for(local_cache_key, value)
28
- @registry[local_cache_key] = value
24
+ registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
25
+ registry[local_cache_key] = value
29
26
  end
30
-
31
- def self.set_cache_for(l, v); instance.set_cache_for l, v; end
32
- def self.cache_for(l); instance.cache_for l; end
33
27
  end
34
28
 
35
29
  # Simple memory backed cache. This cache is not thread safe and is intended only
@@ -372,56 +372,153 @@ module ActiveSupport
372
372
 
373
373
  # A future invocation of user-supplied code (either as a callback,
374
374
  # or a condition filter).
375
- class CallTemplate # :nodoc:
376
- def initialize(target, method, arguments, block)
377
- @override_target = target
378
- @method_name = method
379
- @arguments = arguments
380
- @override_block = block
375
+ module CallTemplate # :nodoc:
376
+ class MethodCall
377
+ def initialize(method)
378
+ @method_name = method
379
+ end
380
+
381
+ # Return the parts needed to make this call, with the given
382
+ # input values.
383
+ #
384
+ # Returns an array of the form:
385
+ #
386
+ # [target, block, method, *arguments]
387
+ #
388
+ # This array can be used as such:
389
+ #
390
+ # target.send(method, *arguments, &block)
391
+ #
392
+ # The actual invocation is left up to the caller to minimize
393
+ # call stack pollution.
394
+ def expand(target, value, block)
395
+ [target, block, @method_name]
396
+ end
397
+
398
+ def make_lambda
399
+ lambda do |target, value, &block|
400
+ target.send(@method_name, &block)
401
+ end
402
+ end
403
+
404
+ def inverted_lambda
405
+ lambda do |target, value, &block|
406
+ !target.send(@method_name, &block)
407
+ end
408
+ end
381
409
  end
382
410
 
383
- # Return the parts needed to make this call, with the given
384
- # input values.
385
- #
386
- # Returns an array of the form:
387
- #
388
- # [target, block, method, *arguments]
389
- #
390
- # This array can be used as such:
391
- #
392
- # target.send(method, *arguments, &block)
393
- #
394
- # The actual invocation is left up to the caller to minimize
395
- # call stack pollution.
396
- def expand(target, value, block)
397
- expanded = [@override_target || target, @override_block || block, @method_name]
411
+ class ObjectCall
412
+ def initialize(target, method)
413
+ @override_target = target
414
+ @method_name = method
415
+ end
416
+
417
+ def expand(target, value, block)
418
+ [@override_target || target, block, @method_name, target]
419
+ end
420
+
421
+ def make_lambda
422
+ lambda do |target, value, &block|
423
+ (@override_target || target).send(@method_name, target, &block)
424
+ end
425
+ end
426
+
427
+ def inverted_lambda
428
+ lambda do |target, value, &block|
429
+ !(@override_target || target).send(@method_name, target, &block)
430
+ end
431
+ end
432
+ end
433
+
434
+ class InstanceExec0
435
+ def initialize(block)
436
+ @override_block = block
437
+ end
438
+
439
+ def expand(target, value, block)
440
+ [target, @override_block, :instance_exec]
441
+ end
442
+
443
+ def make_lambda
444
+ lambda do |target, value, &block|
445
+ target.instance_exec(&@override_block)
446
+ end
447
+ end
398
448
 
399
- @arguments.each do |arg|
400
- case arg
401
- when :value then expanded << value
402
- when :target then expanded << target
403
- when :block then expanded << (block || raise(ArgumentError))
449
+ def inverted_lambda
450
+ lambda do |target, value, &block|
451
+ !target.instance_exec(&@override_block)
452
+ end
453
+ end
454
+ end
455
+
456
+ class InstanceExec1
457
+ def initialize(block)
458
+ @override_block = block
459
+ end
460
+
461
+ def expand(target, value, block)
462
+ [target, @override_block, :instance_exec, target]
463
+ end
464
+
465
+ def make_lambda
466
+ lambda do |target, value, &block|
467
+ target.instance_exec(target, &@override_block)
404
468
  end
405
469
  end
406
470
 
407
- expanded
471
+ def inverted_lambda
472
+ lambda do |target, value, &block|
473
+ !target.instance_exec(target, &@override_block)
474
+ end
475
+ end
408
476
  end
409
477
 
410
- # Return a lambda that will make this call when given the input
411
- # values.
412
- def make_lambda
413
- lambda do |target, value, &block|
414
- target, block, method, *arguments = expand(target, value, block)
415
- target.send(method, *arguments, &block)
478
+ class InstanceExec2
479
+ def initialize(block)
480
+ @override_block = block
481
+ end
482
+
483
+ def expand(target, value, block)
484
+ raise ArgumentError unless block
485
+ [target, @override_block || block, :instance_exec, target, block]
486
+ end
487
+
488
+ def make_lambda
489
+ lambda do |target, value, &block|
490
+ raise ArgumentError unless block
491
+ target.instance_exec(target, block, &@override_block)
492
+ end
493
+ end
494
+
495
+ def inverted_lambda
496
+ lambda do |target, value, &block|
497
+ raise ArgumentError unless block
498
+ !target.instance_exec(target, block, &@override_block)
499
+ end
416
500
  end
417
501
  end
418
502
 
419
- # Return a lambda that will make this call when given the input
420
- # values, but then return the boolean inverse of that result.
421
- def inverted_lambda
422
- lambda do |target, value, &block|
423
- target, block, method, *arguments = expand(target, value, block)
424
- ! target.send(method, *arguments, &block)
503
+ class ProcCall
504
+ def initialize(target)
505
+ @override_target = target
506
+ end
507
+
508
+ def expand(target, value, block)
509
+ [@override_target || target, block, :call, target, value]
510
+ end
511
+
512
+ def make_lambda
513
+ lambda do |target, value, &block|
514
+ (@override_target || target).call(target, value, &block)
515
+ end
516
+ end
517
+
518
+ def inverted_lambda
519
+ lambda do |target, value, &block|
520
+ !(@override_target || target).call(target, value, &block)
521
+ end
425
522
  end
426
523
  end
427
524
 
@@ -436,21 +533,19 @@ module ActiveSupport
436
533
  def self.build(filter, callback)
437
534
  case filter
438
535
  when Symbol
439
- new(nil, filter, [], nil)
536
+ MethodCall.new(filter)
440
537
  when Conditionals::Value
441
- new(filter, :call, [:target, :value], nil)
538
+ ProcCall.new(filter)
442
539
  when ::Proc
443
540
  if filter.arity > 1
444
- new(nil, :instance_exec, [:target, :block], filter)
541
+ InstanceExec2.new(filter)
445
542
  elsif filter.arity > 0
446
- new(nil, :instance_exec, [:target], filter)
543
+ InstanceExec1.new(filter)
447
544
  else
448
- new(nil, :instance_exec, [], filter)
545
+ InstanceExec0.new(filter)
449
546
  end
450
547
  else
451
- method_to_call = callback.current_scopes.join("_")
452
-
453
- new(filter, method_to_call, [:target], nil)
548
+ ObjectCall.new(filter, callback.current_scopes.join("_").to_sym)
454
549
  end
455
550
  end
456
551
  end
@@ -608,7 +703,7 @@ module ActiveSupport
608
703
  # This is used internally to append, prepend and skip callbacks to the
609
704
  # CallbackChain.
610
705
  def __update_callbacks(name) # :nodoc:
611
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse_each do |target|
706
+ ([self] + self.descendants).reverse_each do |target|
612
707
  chain = target.get_callbacks name
613
708
  yield target, chain.dup
614
709
  end
@@ -732,7 +827,7 @@ module ActiveSupport
732
827
  def reset_callbacks(name)
733
828
  callbacks = get_callbacks name
734
829
 
735
- ActiveSupport::DescendantsTracker.descendants(self).each do |target|
830
+ self.descendants.each do |target|
736
831
  chain = target.get_callbacks(name).dup
737
832
  callbacks.each { |c| chain.delete(c) }
738
833
  target.set_callbacks name, chain
@@ -825,7 +920,7 @@ module ActiveSupport
825
920
  names.each do |name|
826
921
  name = name.to_sym
827
922
 
828
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
923
+ ([self] + self.descendants).each do |target|
829
924
  target.set_callbacks name, CallbackChain.new(name, options)
830
925
  end
831
926
 
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ class CodeGenerator # :nodoc:
5
+ class MethodSet
6
+ METHOD_CACHES = Hash.new { |h, k| h[k] = Module.new }
7
+
8
+ def initialize(namespace)
9
+ @cache = METHOD_CACHES[namespace]
10
+ @sources = []
11
+ @methods = {}
12
+ end
13
+
14
+ def define_cached_method(name, as: name)
15
+ name = name.to_sym
16
+ as = as.to_sym
17
+ @methods.fetch(name) do
18
+ unless @cache.method_defined?(as)
19
+ yield @sources
20
+ end
21
+ @methods[name] = as
22
+ end
23
+ end
24
+
25
+ def apply(owner, path, line)
26
+ unless @sources.empty?
27
+ @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
28
+ end
29
+ @methods.each do |name, as|
30
+ owner.define_method(name, @cache.instance_method(as))
31
+ end
32
+ end
33
+ end
34
+
35
+ class << self
36
+ def batch(owner, path, line)
37
+ if owner.is_a?(CodeGenerator)
38
+ yield owner
39
+ else
40
+ instance = new(owner, path, line)
41
+ result = yield instance
42
+ instance.execute
43
+ result
44
+ end
45
+ end
46
+ end
47
+
48
+ def initialize(owner, path, line)
49
+ @owner = owner
50
+ @path = path
51
+ @line = line
52
+ @namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
53
+ end
54
+
55
+ def define_cached_method(name, namespace:, as: name, &block)
56
+ @namespaces[namespace].define_cached_method(name, as: as, &block)
57
+ end
58
+
59
+ def execute
60
+ @namespaces.each_value do |method_set|
61
+ method_set.apply(@owner, @path, @line - 1)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -87,6 +87,8 @@ class Array
87
87
  # Extends <tt>Array#to_s</tt> to convert a collection of elements into a
88
88
  # comma separated id list if <tt>:db</tt> argument is given as the format.
89
89
  #
90
+ # This method is aliased to <tt>to_fs</tt>.
91
+ #
90
92
  # Blog.all.to_formatted_s(:db) # => "1,2,3"
91
93
  # Blog.none.to_formatted_s(:db) # => "null"
92
94
  # [1,2].to_formatted_s # => "[1, 2]"
@@ -102,8 +104,8 @@ class Array
102
104
  to_default_s
103
105
  end
104
106
  end
107
+ alias_method :to_fs, :to_formatted_s
105
108
  alias_method :to_default_s, :to_s
106
- alias_method :to_s, :to_formatted_s
107
109
 
108
110
  # Returns a string that represents the array in XML by invoking +to_xml+
109
111
  # on each element. Active Record collections delegate their representation
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ NOT_SET = Object.new # :nodoc:
5
+ def to_s(format = NOT_SET) # :nodoc:
6
+ case format
7
+ when :db
8
+ ActiveSupport::Deprecation.warn(
9
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_formatted_s(#{format.inspect}) instead."
10
+ )
11
+ if empty?
12
+ "null"
13
+ else
14
+ collect(&:id).join(",")
15
+ end
16
+ when NOT_SET
17
+ to_default_s
18
+ else
19
+ ActiveSupport::Deprecation.warn(
20
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_formatted_s(#{format.inspect}) instead."
21
+ )
22
+ to_default_s
23
+ end
24
+ end
25
+ end
@@ -3,6 +3,7 @@
3
3
  require "active_support/core_ext/array/wrap"
4
4
  require "active_support/core_ext/array/access"
5
5
  require "active_support/core_ext/array/conversions"
6
+ require "active_support/core_ext/array/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
6
7
  require "active_support/core_ext/array/extract"
7
8
  require "active_support/core_ext/array/extract_options"
8
9
  require "active_support/core_ext/array/grouping"
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/ruby_features"
4
+
3
5
  class Class
4
6
  # Returns an array with all classes that are < than its receiver.
5
7
  #
@@ -18,7 +20,7 @@ class Class
18
20
  ObjectSpace.each_object(singleton_class).reject do |k|
19
21
  k.singleton_class? || k == self
20
22
  end
21
- end
23
+ end unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
22
24
 
23
25
  # Returns an array with the direct children of +self+.
24
26
  #
@@ -29,5 +31,5 @@ class Class
29
31
  # Foo.subclasses # => [Bar]
30
32
  def subclasses
31
33
  descendants.select { |descendant| descendant.superclass == self }
32
- end
34
+ end unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
33
35
  end
@@ -17,7 +17,7 @@ class Date
17
17
  # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
18
18
  # If no config.beginning_of_week was specified, returns :monday.
19
19
  def beginning_of_week
20
- Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
20
+ ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] || beginning_of_week_default || :monday
21
21
  end
22
22
 
23
23
  # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
@@ -25,7 +25,7 @@ class Date
25
25
  # This method accepts any of the following day symbols:
26
26
  # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
27
27
  def beginning_of_week=(week_start)
28
- Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
28
+ ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] = find_beginning_of_week!(week_start)
29
29
  end
30
30
 
31
31
  # Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
@@ -22,12 +22,12 @@ class Date
22
22
 
23
23
  # Convert to a formatted string. See DATE_FORMATS for predefined formats.
24
24
  #
25
- # This method is aliased to <tt>to_s</tt>.
25
+ # This method is aliased to <tt>to_fs</tt>.
26
26
  #
27
27
  # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
28
28
  #
29
29
  # date.to_formatted_s(:db) # => "2007-11-10"
30
- # date.to_s(:db) # => "2007-11-10"
30
+ # date.to_formatted_s(:db) # => "2007-11-10"
31
31
  #
32
32
  # date.to_formatted_s(:short) # => "10 Nov"
33
33
  # date.to_formatted_s(:number) # => "20071110"
@@ -55,8 +55,8 @@ class Date
55
55
  to_default_s
56
56
  end
57
57
  end
58
+ alias_method :to_fs, :to_formatted_s
58
59
  alias_method :to_default_s, :to_s
59
- alias_method :to_s, :to_formatted_s
60
60
 
61
61
  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
62
62
  def readable_inspect
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class Date
6
+ NOT_SET = Object.new # :nodoc:
7
+ def to_s(format = NOT_SET) # :nodoc:
8
+ if formatter = DATE_FORMATS[format]
9
+ ActiveSupport::Deprecation.warn(
10
+ "Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_formatted_s(#{format.inspect}) instead."
11
+ )
12
+ if formatter.respond_to?(:call)
13
+ formatter.call(self).to_s
14
+ else
15
+ strftime(formatter)
16
+ end
17
+ elsif format == NOT_SET
18
+ to_default_s
19
+ else
20
+ ActiveSupport::Deprecation.warn(
21
+ "Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_formatted_s(#{format.inspect}) instead."
22
+ )
23
+ to_default_s
24
+ end
25
+ end
26
+ end