activesupport 7.0.4 → 7.1.5.1

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.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1076 -230
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -6
  5. data/lib/active_support/actionable_error.rb +3 -1
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +30 -5
  8. data/lib/active_support/benchmarkable.rb +1 -0
  9. data/lib/active_support/broadcast_logger.rb +251 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +37 -10
  14. data/lib/active_support/cache/mem_cache_store.rb +100 -76
  15. data/lib/active_support/cache/memory_store.rb +78 -24
  16. data/lib/active_support/cache/null_store.rb +6 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +153 -141
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +29 -14
  20. data/lib/active_support/cache.rb +333 -253
  21. data/lib/active_support/callbacks.rb +44 -21
  22. data/lib/active_support/code_generator.rb +15 -10
  23. data/lib/active_support/concern.rb +4 -2
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/configurable.rb +10 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +2 -1
  28. data/lib/active_support/core_ext/array.rb +0 -1
  29. data/lib/active_support/core_ext/class/subclasses.rb +13 -10
  30. data/lib/active_support/core_ext/date/calculations.rb +15 -0
  31. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  32. data/lib/active_support/core_ext/date.rb +0 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  34. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  35. data/lib/active_support/core_ext/date_time/conversions.rb +6 -2
  36. data/lib/active_support/core_ext/date_time.rb +0 -1
  37. data/lib/active_support/core_ext/digest/uuid.rb +1 -10
  38. data/lib/active_support/core_ext/enumerable.rb +8 -75
  39. data/lib/active_support/core_ext/erb/util.rb +196 -0
  40. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  41. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  42. data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
  43. data/lib/active_support/core_ext/hash/keys.rb +3 -3
  44. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  45. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  46. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  47. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  48. data/lib/active_support/core_ext/module/delegation.rb +81 -37
  49. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  50. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  51. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  52. data/lib/active_support/core_ext/numeric/conversions.rb +2 -0
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  55. data/lib/active_support/core_ext/object/duplicable.rb +25 -16
  56. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  57. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  58. data/lib/active_support/core_ext/object/json.rb +16 -6
  59. data/lib/active_support/core_ext/object/to_query.rb +0 -2
  60. data/lib/active_support/core_ext/object/with.rb +44 -0
  61. data/lib/active_support/core_ext/object/with_options.rb +9 -9
  62. data/lib/active_support/core_ext/object.rb +1 -0
  63. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  64. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  65. data/lib/active_support/core_ext/pathname.rb +1 -0
  66. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  67. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  68. data/lib/active_support/core_ext/range.rb +1 -2
  69. data/lib/active_support/core_ext/securerandom.rb +24 -12
  70. data/lib/active_support/core_ext/string/filters.rb +20 -14
  71. data/lib/active_support/core_ext/string/indent.rb +1 -1
  72. data/lib/active_support/core_ext/string/inflections.rb +16 -9
  73. data/lib/active_support/core_ext/string/output_safety.rb +42 -174
  74. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  75. data/lib/active_support/core_ext/time/calculations.rb +22 -2
  76. data/lib/active_support/core_ext/time/conversions.rb +2 -2
  77. data/lib/active_support/core_ext/time/zones.rb +7 -8
  78. data/lib/active_support/core_ext/time.rb +0 -1
  79. data/lib/active_support/current_attributes.rb +15 -6
  80. data/lib/active_support/deep_mergeable.rb +53 -0
  81. data/lib/active_support/dependencies/autoload.rb +17 -12
  82. data/lib/active_support/deprecation/behaviors.rb +65 -42
  83. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  84. data/lib/active_support/deprecation/deprecators.rb +104 -0
  85. data/lib/active_support/deprecation/disallowed.rb +6 -8
  86. data/lib/active_support/deprecation/instance_delegator.rb +31 -4
  87. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  88. data/lib/active_support/deprecation/proxy_wrappers.rb +37 -22
  89. data/lib/active_support/deprecation/reporting.rb +43 -26
  90. data/lib/active_support/deprecation.rb +32 -5
  91. data/lib/active_support/deprecator.rb +7 -0
  92. data/lib/active_support/descendants_tracker.rb +104 -132
  93. data/lib/active_support/duration/iso8601_serializer.rb +0 -2
  94. data/lib/active_support/duration.rb +2 -1
  95. data/lib/active_support/encrypted_configuration.rb +63 -11
  96. data/lib/active_support/encrypted_file.rb +16 -12
  97. data/lib/active_support/environment_inquirer.rb +22 -2
  98. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  99. data/lib/active_support/error_reporter.rb +121 -35
  100. data/lib/active_support/evented_file_update_checker.rb +17 -2
  101. data/lib/active_support/execution_wrapper.rb +4 -4
  102. data/lib/active_support/file_update_checker.rb +4 -2
  103. data/lib/active_support/fork_tracker.rb +10 -2
  104. data/lib/active_support/gem_version.rb +4 -4
  105. data/lib/active_support/gzip.rb +2 -0
  106. data/lib/active_support/hash_with_indifferent_access.rb +35 -17
  107. data/lib/active_support/html_safe_translation.rb +16 -6
  108. data/lib/active_support/i18n.rb +1 -1
  109. data/lib/active_support/i18n_railtie.rb +20 -13
  110. data/lib/active_support/inflector/inflections.rb +2 -0
  111. data/lib/active_support/inflector/methods.rb +28 -18
  112. data/lib/active_support/inflector/transliterate.rb +3 -1
  113. data/lib/active_support/isolated_execution_state.rb +26 -22
  114. data/lib/active_support/json/decoding.rb +2 -1
  115. data/lib/active_support/json/encoding.rb +25 -43
  116. data/lib/active_support/key_generator.rb +9 -1
  117. data/lib/active_support/lazy_load_hooks.rb +7 -5
  118. data/lib/active_support/locale/en.yml +2 -0
  119. data/lib/active_support/log_subscriber.rb +85 -33
  120. data/lib/active_support/logger.rb +9 -60
  121. data/lib/active_support/logger_thread_safe_level.rb +10 -24
  122. data/lib/active_support/message_encryptor.rb +197 -53
  123. data/lib/active_support/message_encryptors.rb +141 -0
  124. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  125. data/lib/active_support/message_pack/extensions.rb +292 -0
  126. data/lib/active_support/message_pack/serializer.rb +63 -0
  127. data/lib/active_support/message_pack.rb +50 -0
  128. data/lib/active_support/message_verifier.rb +212 -93
  129. data/lib/active_support/message_verifiers.rb +135 -0
  130. data/lib/active_support/messages/codec.rb +65 -0
  131. data/lib/active_support/messages/metadata.rb +111 -45
  132. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  133. data/lib/active_support/messages/rotator.rb +34 -32
  134. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  135. data/lib/active_support/multibyte/chars.rb +2 -0
  136. data/lib/active_support/multibyte/unicode.rb +9 -37
  137. data/lib/active_support/notifications/fanout.rb +245 -81
  138. data/lib/active_support/notifications/instrumenter.rb +87 -22
  139. data/lib/active_support/notifications.rb +3 -3
  140. data/lib/active_support/number_helper/number_converter.rb +14 -5
  141. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  142. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
  143. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  144. data/lib/active_support/number_helper.rb +379 -317
  145. data/lib/active_support/ordered_hash.rb +3 -3
  146. data/lib/active_support/ordered_options.rb +14 -0
  147. data/lib/active_support/parameter_filter.rb +103 -84
  148. data/lib/active_support/proxy_object.rb +2 -0
  149. data/lib/active_support/railtie.rb +33 -21
  150. data/lib/active_support/reloader.rb +12 -4
  151. data/lib/active_support/rescuable.rb +2 -0
  152. data/lib/active_support/secure_compare_rotator.rb +16 -9
  153. data/lib/active_support/string_inquirer.rb +3 -1
  154. data/lib/active_support/subscriber.rb +9 -27
  155. data/lib/active_support/syntax_error_proxy.rb +60 -0
  156. data/lib/active_support/tagged_logging.rb +64 -24
  157. data/lib/active_support/test_case.rb +153 -6
  158. data/lib/active_support/testing/assertions.rb +26 -10
  159. data/lib/active_support/testing/autorun.rb +0 -2
  160. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  161. data/lib/active_support/testing/deprecation.rb +25 -25
  162. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  163. data/lib/active_support/testing/isolation.rb +29 -28
  164. data/lib/active_support/testing/method_call_assertions.rb +21 -8
  165. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  166. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  167. data/lib/active_support/testing/stream.rb +1 -1
  168. data/lib/active_support/testing/strict_warnings.rb +39 -0
  169. data/lib/active_support/testing/time_helpers.rb +37 -15
  170. data/lib/active_support/time_with_zone.rb +8 -37
  171. data/lib/active_support/values/time_zone.rb +18 -7
  172. data/lib/active_support/version.rb +1 -1
  173. data/lib/active_support/xml_mini/jdom.rb +3 -10
  174. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  175. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  176. data/lib/active_support/xml_mini/rexml.rb +1 -1
  177. data/lib/active_support/xml_mini.rb +2 -2
  178. data/lib/active_support.rb +14 -3
  179. metadata +148 -19
  180. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  181. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
  182. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
  183. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  184. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
  185. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
  186. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  187. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
  188. data/lib/active_support/core_ext/uri.rb +0 -5
  189. data/lib/active_support/per_thread_registry.rb +0 -65
@@ -9,7 +9,9 @@ require "active_support/core_ext/object/blank"
9
9
  require "thread"
10
10
 
11
11
  module ActiveSupport
12
- # Callbacks are code hooks that are run at key points in an object's life cycle.
12
+ # = Active Support \Callbacks
13
+ #
14
+ # \Callbacks are code hooks that are run at key points in an object's life cycle.
13
15
  # The typical use case is to have a base class define a set of callbacks
14
16
  # relevant to the other functionality it supplies, so that subclasses can
15
17
  # install callbacks that enhance or modify the base functionality without
@@ -68,7 +70,7 @@ module ActiveSupport
68
70
  class_attribute :__callbacks, instance_writer: false, default: {}
69
71
  end
70
72
 
71
- CALLBACK_FILTER_TYPES = [:before, :after, :around]
73
+ CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze
72
74
 
73
75
  # Runs the callbacks for the given event.
74
76
  #
@@ -92,14 +94,15 @@ module ActiveSupport
92
94
  # callback can be as noisy as it likes -- but when control has passed
93
95
  # smoothly through and into the supplied block, we want as little evidence
94
96
  # as possible that we were here.
95
- def run_callbacks(kind)
97
+ def run_callbacks(kind, type = nil)
96
98
  callbacks = __callbacks[kind.to_sym]
97
99
 
98
100
  if callbacks.empty?
99
101
  yield if block_given?
100
102
  else
101
103
  env = Filters::Environment.new(self, false, nil)
102
- next_sequence = callbacks.compile
104
+
105
+ next_sequence = callbacks.compile(type)
103
106
 
104
107
  # Common case: no 'around' callbacks defined
105
108
  if next_sequence.final?
@@ -612,7 +615,8 @@ module ActiveSupport
612
615
  terminator: default_terminator
613
616
  }.merge!(config)
614
617
  @chain = []
615
- @callbacks = nil
618
+ @all_callbacks = nil
619
+ @single_callbacks = {}
616
620
  @mutex = Mutex.new
617
621
  end
618
622
 
@@ -621,32 +625,45 @@ module ActiveSupport
621
625
  def empty?; @chain.empty?; end
622
626
 
623
627
  def insert(index, o)
624
- @callbacks = nil
628
+ @all_callbacks = nil
629
+ @single_callbacks.clear
625
630
  @chain.insert(index, o)
626
631
  end
627
632
 
628
633
  def delete(o)
629
- @callbacks = nil
634
+ @all_callbacks = nil
635
+ @single_callbacks.clear
630
636
  @chain.delete(o)
631
637
  end
632
638
 
633
639
  def clear
634
- @callbacks = nil
640
+ @all_callbacks = nil
641
+ @single_callbacks.clear
635
642
  @chain.clear
636
643
  self
637
644
  end
638
645
 
639
646
  def initialize_copy(other)
640
- @callbacks = nil
647
+ @all_callbacks = nil
648
+ @single_callbacks = {}
641
649
  @chain = other.chain.dup
642
650
  @mutex = Mutex.new
643
651
  end
644
652
 
645
- def compile
646
- @callbacks || @mutex.synchronize do
647
- final_sequence = CallbackSequence.new
648
- @callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
649
- callback.apply callback_sequence
653
+ def compile(type)
654
+ if type.nil?
655
+ @all_callbacks || @mutex.synchronize do
656
+ final_sequence = CallbackSequence.new
657
+ @all_callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
658
+ callback.apply(callback_sequence)
659
+ end
660
+ end
661
+ else
662
+ @single_callbacks[type] || @mutex.synchronize do
663
+ final_sequence = CallbackSequence.new
664
+ @single_callbacks[type] ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
665
+ type == callback.kind ? callback.apply(callback_sequence) : callback_sequence
666
+ end
650
667
  end
651
668
  end
652
669
  end
@@ -664,19 +681,22 @@ module ActiveSupport
664
681
 
665
682
  private
666
683
  def append_one(callback)
667
- @callbacks = nil
684
+ @all_callbacks = nil
685
+ @single_callbacks.clear
668
686
  remove_duplicates(callback)
669
687
  @chain.push(callback)
670
688
  end
671
689
 
672
690
  def prepend_one(callback)
673
- @callbacks = nil
691
+ @all_callbacks = nil
692
+ @single_callbacks.clear
674
693
  remove_duplicates(callback)
675
694
  @chain.unshift(callback)
676
695
  end
677
696
 
678
697
  def remove_duplicates(callback)
679
- @callbacks = nil
698
+ @all_callbacks = nil
699
+ @single_callbacks.clear
680
700
  @chain.delete_if { |c| callback.duplicates?(c) }
681
701
  end
682
702
 
@@ -703,7 +723,7 @@ module ActiveSupport
703
723
  # This is used internally to append, prepend and skip callbacks to the
704
724
  # CallbackChain.
705
725
  def __update_callbacks(name) # :nodoc:
706
- ([self] + self.descendants).reverse_each do |target|
726
+ self.descendants.prepend(self).reverse_each do |target|
707
727
  chain = target.get_callbacks name
708
728
  yield target, chain.dup
709
729
  end
@@ -723,7 +743,7 @@ module ActiveSupport
723
743
  #
724
744
  # The callback can be specified as a symbol naming an instance method; as a
725
745
  # proc, lambda, or block; or as an object that responds to a certain method
726
- # determined by the <tt>:scope</tt> argument to +define_callbacks+.
746
+ # determined by the <tt>:scope</tt> argument to #define_callbacks.
727
747
  #
728
748
  # If a proc, lambda, or block is given, its body is evaluated in the context
729
749
  # of the current object. It can also optionally accept the current object as
@@ -767,10 +787,13 @@ module ActiveSupport
767
787
  end
768
788
  end
769
789
 
770
- # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or
790
+ # Skip a previously set callback. Like #set_callback, <tt>:if</tt> or
771
791
  # <tt>:unless</tt> options may be passed in order to control when the
772
792
  # callback is skipped.
773
793
  #
794
+ # Note: this example uses +PersonRecord+ and +#saving_message+, which you
795
+ # can see defined here[rdoc-ref:ActiveSupport::Callbacks]
796
+ #
774
797
  # class Writer < PersonRecord
775
798
  # attr_accessor :age
776
799
  # skip_callback :save, :before, :saving_message, if: -> { age > 18 }
@@ -913,7 +936,7 @@ module ActiveSupport
913
936
  # <tt>!</tt>, <tt>?</tt> or <tt>=</tt>.
914
937
  #
915
938
  # Calling +define_callbacks+ multiple times with the same +names+ will
916
- # overwrite previous callbacks registered with +set_callback+.
939
+ # overwrite previous callbacks registered with #set_callback.
917
940
  def define_callbacks(*names)
918
941
  options = names.extract_options!
919
942
 
@@ -9,16 +9,19 @@ module ActiveSupport
9
9
  @cache = METHOD_CACHES[namespace]
10
10
  @sources = []
11
11
  @methods = {}
12
+ @canonical_methods = {}
12
13
  end
13
14
 
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)
15
+ def define_cached_method(canonical_name, as: nil)
16
+ canonical_name = canonical_name.to_sym
17
+ as = (as || canonical_name).to_sym
18
+
19
+ @methods.fetch(as) do
20
+ unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name]
19
21
  yield @sources
20
22
  end
21
- @methods[name] = as
23
+ @canonical_methods[canonical_name] = true
24
+ @methods[as] = canonical_name
22
25
  end
23
26
  end
24
27
 
@@ -26,8 +29,10 @@ module ActiveSupport
26
29
  unless @sources.empty?
27
30
  @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
28
31
  end
29
- @methods.each do |name, as|
30
- owner.define_method(name, @cache.instance_method(as))
32
+ @canonical_methods.clear
33
+
34
+ @methods.each do |as, canonical_name|
35
+ owner.define_method(as, @cache.instance_method(canonical_name))
31
36
  end
32
37
  end
33
38
  end
@@ -52,8 +57,8 @@ module ActiveSupport
52
57
  @namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
53
58
  end
54
59
 
55
- def define_cached_method(name, namespace:, as: name, &block)
56
- @namespaces[namespace].define_cached_method(name, as: as, &block)
60
+ def define_cached_method(canonical_name, namespace:, as: nil, &block)
61
+ @namespaces[namespace].define_cached_method(canonical_name, as: as, &block)
57
62
  end
58
63
 
59
64
  def execute
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
+ # = Active Support \Concern
5
+ #
4
6
  # A typical module looks like this:
5
7
  #
6
8
  # module M
@@ -16,7 +18,7 @@ module ActiveSupport
16
18
  # end
17
19
  # end
18
20
  #
19
- # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
21
+ # By using +ActiveSupport::Concern+ the above module could instead be
20
22
  # written as:
21
23
  #
22
24
  # require "active_support/concern"
@@ -73,7 +75,7 @@ module ActiveSupport
73
75
  # end
74
76
  #
75
77
  # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
76
- # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
78
+ # is the +Bar+ module, not the +Host+ class. With +ActiveSupport::Concern+,
77
79
  # module dependencies are properly resolved:
78
80
  #
79
81
  # require "active_support/concern"
@@ -4,9 +4,7 @@ require "monitor"
4
4
 
5
5
  module ActiveSupport
6
6
  module Concurrency
7
- # A monitor that will permit dependency loading while blocked waiting for
8
- # the lock.
9
- class LoadInterlockAwareMonitor < Monitor
7
+ module LoadInterlockAwareMonitorMixin # :nodoc:
10
8
  EXCEPTION_NEVER = { Exception => :never }.freeze
11
9
  EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
12
10
  private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
@@ -29,5 +27,46 @@ module ActiveSupport
29
27
  end
30
28
  end
31
29
  end
30
+ # A monitor that will permit dependency loading while blocked waiting for
31
+ # the lock.
32
+ class LoadInterlockAwareMonitor < Monitor
33
+ include LoadInterlockAwareMonitorMixin
34
+ end
35
+
36
+ class ThreadLoadInterlockAwareMonitor # :nodoc:
37
+ prepend LoadInterlockAwareMonitorMixin
38
+
39
+ def initialize
40
+ @owner = nil
41
+ @count = 0
42
+ @mutex = Mutex.new
43
+ end
44
+
45
+ private
46
+ def mon_try_enter
47
+ if @owner != Thread.current
48
+ return false unless @mutex.try_lock
49
+ @owner = Thread.current
50
+ end
51
+ @count += 1
52
+ end
53
+
54
+ def mon_enter
55
+ @mutex.lock if @owner != Thread.current
56
+ @owner = Thread.current
57
+ @count += 1
58
+ end
59
+
60
+ def mon_exit
61
+ unless @owner == Thread.current
62
+ raise ThreadError, "current thread not owner"
63
+ end
64
+
65
+ @count -= 1
66
+ return unless @count == 0
67
+ @owner = nil
68
+ @mutex.unlock
69
+ end
70
+ end
32
71
  end
33
72
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Concurrency
5
+ module NullLock # :nodoc:
6
+ extend self
7
+
8
+ def synchronize
9
+ yield
10
+ end
11
+ end
12
+ end
13
+ end
@@ -4,6 +4,8 @@ require "active_support/concern"
4
4
  require "active_support/ordered_options"
5
5
 
6
6
  module ActiveSupport
7
+ # = Active Support \Configurable
8
+ #
7
9
  # Configurable provides a <tt>config</tt> method to store and retrieve
8
10
  # configuration options as an OrderedOptions.
9
11
  module Configurable
@@ -125,6 +127,14 @@ module ActiveSupport
125
127
  end
126
128
  end
127
129
  private :config_accessor
130
+
131
+ private
132
+ def inherited(subclass)
133
+ super
134
+ subclass.class_eval do
135
+ @_config = nil
136
+ end
137
+ end
128
138
  end
129
139
 
130
140
  # Reads and writes attributes from a configuration OrderedOptions.
@@ -100,11 +100,12 @@ class Array
100
100
  collect(&:id).join(",")
101
101
  end
102
102
  else
103
- to_default_s
103
+ to_s
104
104
  end
105
105
  end
106
106
  alias_method :to_formatted_s, :to_fs
107
107
  alias_method :to_default_s, :to_s
108
+ deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
108
109
 
109
110
  # Returns a string that represents the array in XML by invoking +to_xml+
110
111
  # on each element. Active Record collections delegate their representation
@@ -3,7 +3,6 @@
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"]
7
6
  require "active_support/core_ext/array/extract"
8
7
  require "active_support/core_ext/array/extract_options"
9
8
  require "active_support/core_ext/array/grouping"
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/ruby_features"
4
+ require "active_support/descendants_tracker"
4
5
 
5
6
  class Class
6
7
  if ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
@@ -26,16 +27,18 @@ class Class
26
27
  k.singleton_class? || k == self
27
28
  end
28
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
29
41
  end
30
42
 
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 unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
43
+ prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
41
44
  end
@@ -109,6 +109,21 @@ class Date
109
109
 
110
110
  # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
111
111
  # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
112
+ #
113
+ # The increments are applied in order of time units from largest to smallest.
114
+ # In other words, the date is incremented first by +:years+, then by
115
+ # +:months+, then by +:weeks+, then by +:days+. This order can affect the
116
+ # result around the end of a month. For example, incrementing first by months
117
+ # then by days:
118
+ #
119
+ # Date.new(2004, 9, 30).advance(months: 1, days: 1)
120
+ # # => Sun, 31 Oct 2004
121
+ #
122
+ # Whereas incrementing first by days then by months yields a different result:
123
+ #
124
+ # Date.new(2004, 9, 30).advance(days: 1).advance(months: 1)
125
+ # # => Mon, 01 Nov 2004
126
+ #
112
127
  def advance(options)
113
128
  d = self
114
129
 
@@ -52,11 +52,12 @@ class Date
52
52
  strftime(formatter)
53
53
  end
54
54
  else
55
- to_default_s
55
+ to_s
56
56
  end
57
57
  end
58
58
  alias_method :to_formatted_s, :to_fs
59
59
  alias_method :to_default_s, :to_s
60
+ deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
60
61
 
61
62
  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
62
63
  def readable_inspect
@@ -4,5 +4,4 @@ require "active_support/core_ext/date/acts_like"
4
4
  require "active_support/core_ext/date/blank"
5
5
  require "active_support/core_ext/date/calculations"
6
6
  require "active_support/core_ext/date/conversions"
7
- require "active_support/core_ext/date/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
8
7
  require "active_support/core_ext/date/zones"
@@ -157,6 +157,16 @@ module DateAndTime
157
157
  end
158
158
  alias :at_end_of_quarter :end_of_quarter
159
159
 
160
+ # Returns the quarter for a date/time.
161
+ #
162
+ # Date.new(2010, 1, 31).quarter # => 1
163
+ # Date.new(2010, 4, 12).quarter # => 2
164
+ # Date.new(2010, 9, 15).quarter # => 3
165
+ # Date.new(2010, 12, 25).quarter # => 4
166
+ def quarter
167
+ (month / 3.0).ceil
168
+ end
169
+
160
170
  # Returns a new date/time at the beginning of the year.
161
171
  #
162
172
  # today = Date.today # => Fri, 10 Jul 2015
@@ -75,6 +75,10 @@ class DateTime
75
75
  # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
76
76
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
77
77
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
78
+ #
79
+ # Just like Date#advance, increments are applied in order of time units from
80
+ # largest to smallest. This order can affect the result around the end of a
81
+ # month.
78
82
  def advance(options)
79
83
  unless options[:weeks].nil?
80
84
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -36,11 +36,15 @@ class DateTime
36
36
  if formatter = ::Time::DATE_FORMATS[format]
37
37
  formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
38
38
  else
39
- to_default_s
39
+ to_s
40
40
  end
41
41
  end
42
42
  alias_method :to_formatted_s, :to_fs
43
- alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
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
+
44
48
 
45
49
  # Returns a formatted string of the offset from UTC, or an alternative
46
50
  # string if the time zone is already UTC.
@@ -5,4 +5,3 @@ require "active_support/core_ext/date_time/blank"
5
5
  require "active_support/core_ext/date_time/calculations"
6
6
  require "active_support/core_ext/date_time/compatibility"
7
7
  require "active_support/core_ext/date_time/conversions"
8
- require "active_support/core_ext/date_time/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
@@ -10,8 +10,6 @@ module Digest
10
10
  OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
11
11
  X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
12
12
 
13
- mattr_accessor :use_rfc4122_namespaced_uuids, instance_accessor: false, default: false
14
-
15
13
  # Generates a v5 non-random UUID (Universally Unique IDentifier).
16
14
  #
17
15
  # Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs.
@@ -58,19 +56,12 @@ module Digest
58
56
  def self.pack_uuid_namespace(namespace)
59
57
  if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace)
60
58
  namespace
61
- elsif use_rfc4122_namespaced_uuids == true
59
+ else
62
60
  match_data = namespace.match(/\A(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})\z/)
63
61
 
64
62
  raise ArgumentError, "Only UUIDs are valid namespace identifiers" unless match_data.present?
65
63
 
66
64
  match_data.captures.map { |s| s.to_i(16) }.pack("NnnnnN")
67
- else
68
- ActiveSupport::Deprecation.warn <<~WARNING.squish
69
- Providing a namespace ID that is not one of the constants defined on Digest::UUID generates an incorrect UUID value according to RFC 4122.
70
- To enable the correct behavior, set the Rails.application.config.active_support.use_rfc4122_namespaced_uuids configuration option to true.
71
- WARNING
72
-
73
- namespace
74
65
  end
75
66
  end
76
67
 
@@ -25,18 +25,6 @@ module Enumerable
25
25
  ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError)
26
26
  singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants)
27
27
 
28
- # Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
29
- # when we omit an identity.
30
-
31
- # :stopdoc:
32
-
33
- # We can't use Refinements here because Refinements with Module which will be prepended
34
- # doesn't work well https://bugs.ruby-lang.org/issues/13446
35
- alias :_original_sum_with_required_identity :sum
36
- private :_original_sum_with_required_identity
37
-
38
- # :startdoc:
39
-
40
28
  # Calculates the minimum from the extracted elements.
41
29
  #
42
30
  # payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
@@ -53,45 +41,6 @@ module Enumerable
53
41
  map(&key).max
54
42
  end
55
43
 
56
- # Calculates a sum from the elements.
57
- #
58
- # payments.sum { |p| p.price * p.tax_rate }
59
- # payments.sum(&:price)
60
- #
61
- # The latter is a shortcut for:
62
- #
63
- # payments.inject(0) { |sum, p| sum + p.price }
64
- #
65
- # It can also calculate the sum without the use of a block.
66
- #
67
- # [5, 15, 10].sum # => 30
68
- # ['foo', 'bar'].sum('') # => "foobar"
69
- # [[1, 2], [3, 1, 5]].sum([]) # => [1, 2, 3, 1, 5]
70
- #
71
- # The default sum of an empty list is zero. You can override this default:
72
- #
73
- # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
74
- def sum(identity = nil, &block)
75
- if identity
76
- _original_sum_with_required_identity(identity, &block)
77
- elsif block_given?
78
- map(&block).sum
79
- # we check `first(1) == []` to check if we have an
80
- # empty Enumerable; checking `empty?` would return
81
- # true for `[nil]`, which we want to deprecate to
82
- # keep consistent with Ruby
83
- elsif first.is_a?(Numeric) || first(1) == []
84
- identity ||= 0
85
- _original_sum_with_required_identity(identity, &block)
86
- else
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
- inject(:+) || 0
92
- end
93
- end
94
-
95
44
  # Convert an enumerable to a hash, using the block result as the key and the
96
45
  # element as the value.
97
46
  #
@@ -144,8 +93,8 @@ module Enumerable
144
93
  def many?
145
94
  cnt = 0
146
95
  if block_given?
147
- any? do |element|
148
- cnt += 1 if yield element
96
+ any? do |*args|
97
+ cnt += 1 if yield(*args)
149
98
  cnt > 1
150
99
  end
151
100
  else
@@ -225,8 +174,8 @@ module Enumerable
225
174
  # [1, "", nil, 2, " ", [], {}, false, true].compact_blank
226
175
  # # => [1, 2, true]
227
176
  #
228
- # Set.new([nil, "", 1, 2])
229
- # # => [2, 1] (or [1, 2])
177
+ # Set.new([nil, "", 1, false]).compact_blank
178
+ # # => [1]
230
179
  #
231
180
  # When called on a +Hash+, returns a new +Hash+ without the blank values.
232
181
  #
@@ -245,7 +194,7 @@ module Enumerable
245
194
  # If the +series+ include keys that have no corresponding element in the Enumerable, these are ignored.
246
195
  # If the Enumerable has additional elements that aren't named in the +series+, these are not included in the result.
247
196
  def in_order_of(key, series)
248
- index_by(&key).values_at(*series).compact
197
+ group_by(&key).values_at(*series).flatten(1).compact
249
198
  end
250
199
 
251
200
  # Returns the sole item in the enumerable. If there are no items, or more
@@ -284,38 +233,22 @@ end
284
233
  class Range # :nodoc:
285
234
  # Optimize range sum to use arithmetic progression if a block is not given and
286
235
  # we have a range of numeric values.
287
- def sum(identity = nil)
236
+ def sum(initial_value = 0)
288
237
  if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
289
238
  super
290
239
  else
291
240
  actual_last = exclude_end? ? (last - 1) : last
292
241
  if actual_last >= first
293
- sum = identity || 0
242
+ sum = initial_value || 0
294
243
  sum + (actual_last - first + 1) * (actual_last + first) / 2
295
244
  else
296
- identity || 0
245
+ initial_value || 0
297
246
  end
298
247
  end
299
248
  end
300
249
  end
301
250
 
302
- # Using Refinements here in order not to expose our internal method
303
- using Module.new {
304
- refine Array do
305
- alias :orig_sum :sum
306
- end
307
- }
308
-
309
251
  class Array # :nodoc:
310
- def sum(init = nil, &block)
311
- if init.is_a?(Numeric) || first.is_a?(Numeric)
312
- init ||= 0
313
- orig_sum(init, &block)
314
- else
315
- super
316
- end
317
- end
318
-
319
252
  # Removes all blank elements from the +Array+ in place and returns self.
320
253
  # Uses Object#blank? for determining if an item is blank.
321
254
  #