activesupport 5.1.1 → 6.1.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.

Files changed (262) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -442
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +65 -53
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +68 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +305 -127
  19. data/lib/active_support/callbacks.rb +106 -98
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +46 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +6 -101
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +7 -2
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +76 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +73 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +208 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  146. data/lib/active_support/dependencies.rb +135 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +30 -15
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +20 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +179 -41
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +3 -0
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +62 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +134 -37
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +20 -11
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +33 -10
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +46 -13
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +101 -33
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +41 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +3 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +11 -10
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -4
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +8 -4
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +55 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +81 -35
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  require "thread"
3
5
  require "concurrent/map"
@@ -10,7 +12,6 @@ require "active_support/core_ext/object/blank"
10
12
  require "active_support/core_ext/kernel/reporting"
11
13
  require "active_support/core_ext/load_error"
12
14
  require "active_support/core_ext/name_error"
13
- require "active_support/core_ext/string/starts_ends_with"
14
15
  require "active_support/dependencies/interlock"
15
16
  require "active_support/inflector"
16
17
 
@@ -18,8 +19,10 @@ module ActiveSupport #:nodoc:
18
19
  module Dependencies #:nodoc:
19
20
  extend self
20
21
 
21
- mattr_accessor :interlock
22
- self.interlock = Interlock.new
22
+ UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
23
+ private_constant :UNBOUND_METHOD_MODULE_NAME
24
+
25
+ mattr_accessor :interlock, default: Interlock.new
23
26
 
24
27
  # :doc:
25
28
 
@@ -46,46 +49,48 @@ module ActiveSupport #:nodoc:
46
49
  # :nodoc:
47
50
 
48
51
  # Should we turn on Ruby warnings on the first load of dependent files?
49
- mattr_accessor :warnings_on_first_load
50
- self.warnings_on_first_load = false
52
+ mattr_accessor :warnings_on_first_load, default: false
51
53
 
52
54
  # All files ever loaded.
53
- mattr_accessor :history
54
- self.history = Set.new
55
+ mattr_accessor :history, default: Set.new
55
56
 
56
57
  # All files currently loaded.
57
- mattr_accessor :loaded
58
- self.loaded = Set.new
58
+ mattr_accessor :loaded, default: Set.new
59
59
 
60
60
  # Stack of files being loaded.
61
- mattr_accessor :loading
62
- self.loading = []
61
+ mattr_accessor :loading, default: []
63
62
 
64
63
  # Should we load files or require them?
65
- mattr_accessor :mechanism
66
- self.mechanism = ENV["NO_RELOAD"] ? :require : :load
64
+ mattr_accessor :mechanism, default: ENV["NO_RELOAD"] ? :require : :load
67
65
 
68
66
  # The set of directories from which we may automatically load files. Files
69
67
  # under these directories will be reloaded on each request in development mode,
70
68
  # unless the directory also appears in autoload_once_paths.
71
- mattr_accessor :autoload_paths
72
- self.autoload_paths = []
69
+ mattr_accessor :autoload_paths, default: []
73
70
 
74
71
  # The set of directories from which automatically loaded constants are loaded
75
72
  # only once. All directories in this set must also be present in +autoload_paths+.
76
- mattr_accessor :autoload_once_paths
77
- self.autoload_once_paths = []
73
+ mattr_accessor :autoload_once_paths, default: []
74
+
75
+ # This is a private set that collects all eager load paths during bootstrap.
76
+ # Useful for Zeitwerk integration. Its public interface is the config.* path
77
+ # accessors of each engine.
78
+ mattr_accessor :_eager_load_paths, default: Set.new
78
79
 
79
80
  # An array of qualified constant names that have been loaded. Adding a name
80
81
  # to this array will cause it to be unloaded the next time Dependencies are
81
82
  # cleared.
82
- mattr_accessor :autoloaded_constants
83
- self.autoloaded_constants = []
83
+ mattr_accessor :autoloaded_constants, default: []
84
84
 
85
85
  # An array of constant names that need to be unloaded on every request. Used
86
86
  # to allow arbitrary constants to be marked for unloading.
87
- mattr_accessor :explicitly_unloadable_constants
88
- self.explicitly_unloadable_constants = []
87
+ mattr_accessor :explicitly_unloadable_constants, default: []
88
+
89
+ # The logger used when tracing autoloads.
90
+ mattr_accessor :logger
91
+
92
+ # If true, trace autoloads with +logger.debug+.
93
+ mattr_accessor :verbose, default: false
89
94
 
90
95
  # The WatchStack keeps a stack of the modules being watched as files are
91
96
  # loaded. If a file in the process of being loaded (parent.rb) triggers the
@@ -93,7 +98,7 @@ module ActiveSupport #:nodoc:
93
98
  # handles the new constants.
94
99
  #
95
100
  # If child.rb is being autoloaded, its constants will be added to
96
- # autoloaded_constants. If it was being `require`d, they will be discarded.
101
+ # autoloaded_constants. If it was being required, they will be discarded.
97
102
  #
98
103
  # This is handled by walking back up the watch stack and adding the constants
99
104
  # found by child.rb to the list of original constants in parent.rb.
@@ -105,6 +110,8 @@ module ActiveSupport #:nodoc:
105
110
  # parent.rb then requires namespace/child.rb, the stack will look like
106
111
  # [[Object], [Namespace]].
107
112
 
113
+ attr_reader :watching
114
+
108
115
  def initialize
109
116
  @watching = []
110
117
  @stack = Hash.new { |h, k| h[k] = [] }
@@ -146,7 +153,7 @@ module ActiveSupport #:nodoc:
146
153
 
147
154
  # Normalize the list of new constants, and add them to the list we will return
148
155
  new_constants.each do |suffix|
149
- constants << ([namespace, suffix] - ["Object"]).join("::".freeze)
156
+ constants << ([namespace, suffix] - ["Object"]).join("::")
150
157
  end
151
158
  end
152
159
  constants
@@ -175,8 +182,7 @@ module ActiveSupport #:nodoc:
175
182
  end
176
183
 
177
184
  # An internal stack used to record which constants are loaded by any block.
178
- mattr_accessor :constant_watch_stack
179
- self.constant_watch_stack = WatchStack.new
185
+ mattr_accessor :constant_watch_stack, default: WatchStack.new
180
186
 
181
187
  # Module includes this module.
182
188
  module ModuleConstMissing #:nodoc:
@@ -197,6 +203,11 @@ module ActiveSupport #:nodoc:
197
203
  end
198
204
  end
199
205
 
206
+ def self.include_into(base)
207
+ base.include(self)
208
+ append_features(base)
209
+ end
210
+
200
211
  def const_missing(const_name)
201
212
  from_mod = anonymous? ? guess_for_anonymous(const_name) : self
202
213
  Dependencies.load_missing_constant(from_mod, const_name)
@@ -226,6 +237,21 @@ module ActiveSupport #:nodoc:
226
237
  base.class_eval do
227
238
  define_method(:load, Kernel.instance_method(:load))
228
239
  private :load
240
+
241
+ define_method(:require, Kernel.instance_method(:require))
242
+ private :require
243
+ end
244
+ end
245
+
246
+ def self.include_into(base)
247
+ base.include(self)
248
+
249
+ if base.instance_method(:load).owner == base
250
+ base.remove_method(:load)
251
+ end
252
+
253
+ if base.instance_method(:require).owner == base
254
+ base.remove_method(:require)
229
255
  end
230
256
  end
231
257
 
@@ -233,15 +259,26 @@ module ActiveSupport #:nodoc:
233
259
  Dependencies.require_or_load(file_name)
234
260
  end
235
261
 
236
- # Interprets a file using <tt>mechanism</tt> and marks its defined
237
- # constants as autoloaded. <tt>file_name</tt> can be either a string or
262
+ # :doc:
263
+
264
+ # <b>Warning:</b> This method is obsolete in +:zeitwerk+ mode. In
265
+ # +:zeitwerk+ mode semantics match Ruby's and you do not need to be
266
+ # defensive with load order. Just refer to classes and modules normally.
267
+ # If the constant name is dynamic, camelize if needed, and constantize.
268
+ #
269
+ # In +:classic+ mode, interprets a file using +mechanism+ and marks its
270
+ # defined constants as autoloaded. +file_name+ can be either a string or
238
271
  # respond to <tt>to_path</tt>.
239
272
  #
240
- # Use this method in code that absolutely needs a certain constant to be
241
- # defined at that point. A typical use case is to make constant name
242
- # resolution deterministic for constants with the same relative name in
243
- # different namespaces whose evaluation would depend on load order
244
- # otherwise.
273
+ # In +:classic+ mode, use this method in code that absolutely needs a
274
+ # certain constant to be defined at that point. A typical use case is to
275
+ # make constant name resolution deterministic for constants with the same
276
+ # relative name in different namespaces whose evaluation would depend on
277
+ # load order otherwise.
278
+ #
279
+ # Engines that do not control the mode in which their parent application
280
+ # runs should call +require_dependency+ where needed in case the runtime
281
+ # mode is +:classic+.
245
282
  def require_dependency(file_name, message = "No such file to load -- %s.rb")
246
283
  file_name = file_name.to_path if file_name.respond_to?(:to_path)
247
284
  unless file_name.is_a?(String)
@@ -251,9 +288,13 @@ module ActiveSupport #:nodoc:
251
288
  Dependencies.depend_on(file_name, message)
252
289
  end
253
290
 
291
+ # :nodoc:
292
+
254
293
  def load_dependency(file)
255
294
  if Dependencies.load? && Dependencies.constant_watch_stack.watching?
256
- Dependencies.new_constants_in(Object) { yield }
295
+ descs = Dependencies.constant_watch_stack.watching.flatten.uniq
296
+
297
+ Dependencies.new_constants_in(*descs) { yield }
257
298
  else
258
299
  yield
259
300
  end
@@ -280,7 +321,6 @@ module ActiveSupport #:nodoc:
280
321
  end
281
322
 
282
323
  private
283
-
284
324
  def load(file, wrap = false)
285
325
  result = false
286
326
  load_dependency(file) { result = super }
@@ -316,9 +356,9 @@ module ActiveSupport #:nodoc:
316
356
  end
317
357
 
318
358
  def hook!
319
- Object.class_eval { include Loadable }
320
- Module.class_eval { include ModuleConstMissing }
321
- Exception.class_eval { include Blamable }
359
+ Loadable.include_into(Object)
360
+ ModuleConstMissing.include_into(Module)
361
+ Exception.include(Blamable)
322
362
  end
323
363
 
324
364
  def unhook!
@@ -335,7 +375,12 @@ module ActiveSupport #:nodoc:
335
375
  require_or_load(path || file_name)
336
376
  rescue LoadError => load_error
337
377
  if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
338
- load_error.message.replace(message % file_name)
378
+ load_error_message = if load_error.respond_to?(:original_message)
379
+ load_error.original_message
380
+ else
381
+ load_error.message
382
+ end
383
+ load_error_message.replace(message % file_name)
339
384
  load_error.copy_blame!(load_error)
340
385
  end
341
386
  raise
@@ -350,7 +395,7 @@ module ActiveSupport #:nodoc:
350
395
  end
351
396
 
352
397
  def require_or_load(file_name, const_path = nil)
353
- file_name = $` if file_name =~ /\.rb\z/
398
+ file_name = file_name.chomp(".rb")
354
399
  expanded = File.expand_path(file_name)
355
400
  return if loaded.include?(expanded)
356
401
 
@@ -400,7 +445,7 @@ module ActiveSupport #:nodoc:
400
445
  # constant paths which would cause Dependencies to attempt to load this
401
446
  # file.
402
447
  def loadable_constants_for_path(path, bases = autoload_paths)
403
- path = $` if path =~ /\.rb\z/
448
+ path = path.chomp(".rb")
404
449
  expanded_path = File.expand_path(path)
405
450
  paths = []
406
451
 
@@ -409,7 +454,7 @@ module ActiveSupport #:nodoc:
409
454
  next unless expanded_path.start_with?(expanded_root)
410
455
 
411
456
  root_size = expanded_root.size
412
- next if expanded_path[root_size] != ?/.freeze
457
+ next if expanded_path[root_size] != ?/
413
458
 
414
459
  nesting = expanded_path[(root_size + 1)..-1]
415
460
  paths << nesting.camelize unless nesting.blank?
@@ -421,7 +466,7 @@ module ActiveSupport #:nodoc:
421
466
 
422
467
  # Search for a file in autoload_paths matching the provided suffix.
423
468
  def search_for_file(path_suffix)
424
- path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb".freeze)
469
+ path_suffix += ".rb" unless path_suffix.end_with?(".rb")
425
470
 
426
471
  autoload_paths.each do |root|
427
472
  path = File.join(root, path_suffix)
@@ -441,9 +486,9 @@ module ActiveSupport #:nodoc:
441
486
  end
442
487
 
443
488
  def load_once_path?(path)
444
- # to_s works around a ruby issue where String#starts_with?(Pathname)
489
+ # to_s works around a ruby issue where String#start_with?(Pathname)
445
490
  # will raise a TypeError: no implicit conversion of Pathname into String
446
- autoload_once_paths.any? { |base| path.starts_with? base.to_s }
491
+ autoload_once_paths.any? { |base| path.start_with?(base.to_s) }
447
492
  end
448
493
 
449
494
  # Attempt to autoload the provided module name by searching for a directory
@@ -455,7 +500,9 @@ module ActiveSupport #:nodoc:
455
500
  return nil unless base_path = autoloadable_module?(path_suffix)
456
501
  mod = Module.new
457
502
  into.const_set const_name, mod
503
+ log("constant #{qualified_name} autoloaded (module autovivified from #{File.join(base_path, path_suffix)})")
458
504
  autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
505
+ autoloaded_constants.uniq!
459
506
  mod
460
507
  end
461
508
 
@@ -491,30 +538,36 @@ module ActiveSupport #:nodoc:
491
538
  # it is not possible to load the constant into from_mod, try its parent
492
539
  # module using +const_missing+.
493
540
  def load_missing_constant(from_mod, const_name)
494
- unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
541
+ from_mod_name = real_mod_name(from_mod)
542
+ unless qualified_const_defined?(from_mod_name) && Inflector.constantize(from_mod_name).equal?(from_mod)
495
543
  raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
496
544
  end
497
545
 
498
- qualified_name = qualified_name_for from_mod, const_name
546
+ qualified_name = qualified_name_for(from_mod, const_name)
499
547
  path_suffix = qualified_name.underscore
500
548
 
501
549
  file_path = search_for_file(path_suffix)
502
550
 
503
551
  if file_path
504
552
  expanded = File.expand_path(file_path)
505
- expanded.sub!(/\.rb\z/, "".freeze)
553
+ expanded.delete_suffix!(".rb")
506
554
 
507
555
  if loading.include?(expanded)
508
556
  raise "Circular dependency detected while autoloading constant #{qualified_name}"
509
557
  else
510
558
  require_or_load(expanded, qualified_name)
511
- raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
512
- return from_mod.const_get(const_name)
559
+
560
+ if from_mod.const_defined?(const_name, false)
561
+ log("constant #{qualified_name} autoloaded from #{expanded}.rb")
562
+ return from_mod.const_get(const_name)
563
+ else
564
+ raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it"
565
+ end
513
566
  end
514
567
  elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
515
568
  return mod
516
- elsif (parent = from_mod.parent) && parent != from_mod &&
517
- ! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
569
+ elsif (parent = from_mod.module_parent) && parent != from_mod &&
570
+ ! from_mod.module_parents.any? { |p| p.const_defined?(const_name, false) }
518
571
  # If our parents do not have a constant named +const_name+ then we are free
519
572
  # to attempt to load upwards. If they do have such a constant, then this
520
573
  # const_missing must be due to from_mod::const_name, which should not
@@ -545,8 +598,8 @@ module ActiveSupport #:nodoc:
545
598
  end
546
599
  end
547
600
 
548
- name_error = NameError.new("uninitialized constant #{qualified_name}", const_name)
549
- name_error.set_backtrace(caller.reject { |l| l.starts_with? __FILE__ })
601
+ name_error = uninitialized_constant(qualified_name, const_name, receiver: from_mod)
602
+ name_error.set_backtrace(caller.reject { |l| l.start_with? __FILE__ })
550
603
  raise name_error
551
604
  end
552
605
 
@@ -558,6 +611,7 @@ module ActiveSupport #:nodoc:
558
611
  # as the environment will be in an inconsistent state, e.g. other constants
559
612
  # may have already been unloaded and not accessible.
560
613
  def remove_unloadable_constants!
614
+ log("removing unloadable constants")
561
615
  autoloaded_constants.each { |const| remove_constant const }
562
616
  autoloaded_constants.clear
563
617
  Reference.clear!
@@ -621,10 +675,10 @@ module ActiveSupport #:nodoc:
621
675
 
622
676
  # Determine if the given constant has been automatically loaded.
623
677
  def autoloaded?(desc)
624
- return false if desc.is_a?(Module) && desc.anonymous?
678
+ return false if desc.is_a?(Module) && real_mod_name(desc).nil?
625
679
  name = to_constant_name desc
626
680
  return false unless qualified_const_defined?(name)
627
- return autoloaded_constants.include?(name)
681
+ autoloaded_constants.include?(name)
628
682
  end
629
683
 
630
684
  # Will the provided constant descriptor be unloaded?
@@ -674,18 +728,18 @@ module ActiveSupport #:nodoc:
674
728
  # A module, class, symbol, or string may be provided.
675
729
  def to_constant_name(desc) #:nodoc:
676
730
  case desc
677
- when String then desc.sub(/^::/, "")
731
+ when String then desc.delete_prefix("::")
678
732
  when Symbol then desc.to_s
679
733
  when Module
680
- desc.name ||
734
+ real_mod_name(desc) ||
681
735
  raise(ArgumentError, "Anonymous modules have no name to be referenced by")
682
- else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
736
+ else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
683
737
  end
684
738
  end
685
739
 
686
740
  def remove_constant(const) #:nodoc:
687
741
  # Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
688
- normalized = const.to_s.sub(/\A::/, "")
742
+ normalized = const.to_s.delete_prefix("::")
689
743
  normalized.sub!(/\A(Object::)+/, "")
690
744
 
691
745
  constants = normalized.split("::")
@@ -695,7 +749,7 @@ module ActiveSupport #:nodoc:
695
749
  file_path = search_for_file(const.underscore)
696
750
  if file_path
697
751
  expanded = File.expand_path(file_path)
698
- expanded.sub!(/\.rb\z/, "")
752
+ expanded.delete_suffix!(".rb")
699
753
  loaded.delete(expanded)
700
754
  end
701
755
 
@@ -747,6 +801,27 @@ module ActiveSupport #:nodoc:
747
801
  # The constant is no longer reachable, just skip it.
748
802
  end
749
803
  end
804
+
805
+ def log(message)
806
+ logger.debug("autoloading: #{message}") if logger && verbose
807
+ end
808
+
809
+ private
810
+ if RUBY_VERSION < "2.6"
811
+ def uninitialized_constant(qualified_name, const_name, receiver:)
812
+ NameError.new("uninitialized constant #{qualified_name}", const_name)
813
+ end
814
+ else
815
+ def uninitialized_constant(qualified_name, const_name, receiver:)
816
+ NameError.new("uninitialized constant #{qualified_name}", const_name, receiver: receiver)
817
+ end
818
+ end
819
+
820
+ # Returns the original name of a class or module even if `name` has been
821
+ # overridden.
822
+ def real_mod_name(mod)
823
+ UNBOUND_METHOD_MODULE_NAME.bind(mod).call
824
+ end
750
825
  end
751
826
  end
752
827
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/notifications"
2
4
 
3
5
  module ActiveSupport
@@ -9,18 +11,18 @@ module ActiveSupport
9
11
  class Deprecation
10
12
  # Default warning behaviors per Rails.env.
11
13
  DEFAULT_BEHAVIORS = {
12
- raise: ->(message, callstack) {
14
+ raise: ->(message, callstack, deprecation_horizon, gem_name) {
13
15
  e = DeprecationException.new(message)
14
16
  e.set_backtrace(callstack.map(&:to_s))
15
17
  raise e
16
18
  },
17
19
 
18
- stderr: ->(message, callstack) {
20
+ stderr: ->(message, callstack, deprecation_horizon, gem_name) {
19
21
  $stderr.puts(message)
20
22
  $stderr.puts callstack.join("\n ") if debug
21
23
  },
22
24
 
23
- log: ->(message, callstack) {
25
+ log: ->(message, callstack, deprecation_horizon, gem_name) {
24
26
  logger =
25
27
  if defined?(Rails.logger) && Rails.logger
26
28
  Rails.logger
@@ -32,12 +34,16 @@ module ActiveSupport
32
34
  logger.debug callstack.join("\n ") if debug
33
35
  },
34
36
 
35
- notify: ->(message, callstack) {
36
- ActiveSupport::Notifications.instrument("deprecation.rails",
37
- message: message, callstack: callstack)
37
+ notify: ->(message, callstack, deprecation_horizon, gem_name) {
38
+ notification_name = "deprecation.#{gem_name.underscore.tr('/', '_')}"
39
+ ActiveSupport::Notifications.instrument(notification_name,
40
+ message: message,
41
+ callstack: callstack,
42
+ gem_name: gem_name,
43
+ deprecation_horizon: deprecation_horizon)
38
44
  },
39
45
 
40
- silence: ->(message, callstack) {},
46
+ silence: ->(message, callstack, deprecation_horizon, gem_name) { },
41
47
  }
42
48
 
43
49
  # Behavior module allows to determine how to display deprecation messages.
@@ -45,7 +51,7 @@ module ActiveSupport
45
51
  # constant. Available behaviors are:
46
52
  #
47
53
  # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
48
- # [+stderr+] Log all deprecation warnings to +$stderr+.
54
+ # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
49
55
  # [+log+] Log all deprecation warnings to +Rails.logger+.
50
56
  # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
51
57
  # [+silence+] Do nothing.
@@ -61,13 +67,18 @@ module ActiveSupport
61
67
  @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
62
68
  end
63
69
 
70
+ # Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+.
71
+ def disallowed_behavior
72
+ @disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
73
+ end
74
+
64
75
  # Sets the behavior to the specified value. Can be a single value, array,
65
76
  # or an object that responds to +call+.
66
77
  #
67
78
  # Available behaviors:
68
79
  #
69
80
  # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
70
- # [+stderr+] Log all deprecation warnings to +$stderr+.
81
+ # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
71
82
  # [+log+] Log all deprecation warnings to +Rails.logger+.
72
83
  # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
73
84
  # [+silence+] Do nothing.
@@ -79,12 +90,33 @@ module ActiveSupport
79
90
  # ActiveSupport::Deprecation.behavior = :stderr
80
91
  # ActiveSupport::Deprecation.behavior = [:stderr, :log]
81
92
  # ActiveSupport::Deprecation.behavior = MyCustomHandler
82
- # ActiveSupport::Deprecation.behavior = ->(message, callstack) {
93
+ # ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
83
94
  # # custom stuff
84
95
  # }
85
96
  def behavior=(behavior)
86
- @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
97
+ @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
87
98
  end
99
+
100
+ # Sets the behavior for disallowed deprecations (those configured by
101
+ # ActiveSupport::Deprecation.disallowed_warnings=) to the specified
102
+ # value. As with +behavior=+, this can be a single value, array, or an
103
+ # object that responds to +call+.
104
+ def disallowed_behavior=(behavior)
105
+ @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
106
+ end
107
+
108
+ private
109
+ def arity_coerce(behavior)
110
+ unless behavior.respond_to?(:call)
111
+ raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
112
+ end
113
+
114
+ if behavior.arity == 4 || behavior.arity == -1
115
+ behavior
116
+ else
117
+ -> message, callstack, _, _ { behavior.call(message, callstack) }
118
+ end
119
+ end
88
120
  end
89
121
  end
90
122
  end
@@ -1,4 +1,4 @@
1
- require "active_support/inflector/methods"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
4
  class Deprecation
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
  #
16
16
  # PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
17
17
  #
18
- # (In a later update, the original implementation of `PLANETS` has been removed.)
18
+ # # (In a later update, the original implementation of `PLANETS` has been removed.)
19
19
  #
20
20
  # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
21
21
  # include ActiveSupport::Deprecation::DeprecatedConstantAccessor
@@ -27,6 +27,8 @@ module ActiveSupport
27
27
  # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
28
28
  module DeprecatedConstantAccessor
29
29
  def self.included(base)
30
+ require "active_support/inflector/methods"
31
+
30
32
  extension = Module.new do
31
33
  def const_missing(missing_const_name)
32
34
  if class_variable_defined?(:@@_deprecated_constants)
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ class Deprecation
5
+ module Disallowed
6
+ # Sets the criteria used to identify deprecation messages which should be
7
+ # disallowed. Can be an array containing strings, symbols, or regular
8
+ # expressions. (Symbols are treated as strings). These are compared against
9
+ # the text of the generated deprecation warning.
10
+ #
11
+ # Additionally the scalar symbol +:all+ may be used to treat all
12
+ # deprecations as disallowed.
13
+ #
14
+ # Deprecations matching a substring or regular expression will be handled
15
+ # using the configured +ActiveSupport::Deprecation.disallowed_behavior+
16
+ # rather than +ActiveSupport::Deprecation.behavior+
17
+ attr_writer :disallowed_warnings
18
+
19
+ # Returns the configured criteria used to identify deprecation messages
20
+ # which should be treated as disallowed.
21
+ def disallowed_warnings
22
+ @disallowed_warnings ||= []
23
+ end
24
+
25
+ private
26
+ def deprecation_disallowed?(message)
27
+ disallowed = ActiveSupport::Deprecation.disallowed_warnings
28
+ return false if explicitly_allowed?(message)
29
+ return true if disallowed == :all
30
+ disallowed.any? do |rule|
31
+ case rule
32
+ when String, Symbol
33
+ message.include?(rule.to_s)
34
+ when Regexp
35
+ rule.match?(message)
36
+ end
37
+ end
38
+ end
39
+
40
+ def explicitly_allowed?(message)
41
+ allowances = @explicitly_allowed_warnings.value
42
+ return false unless allowances
43
+ return true if allowances == :all
44
+ allowances = [allowances] unless allowances.kind_of?(Array)
45
+ allowances.any? do |rule|
46
+ case rule
47
+ when String, Symbol
48
+ message.include?(rule.to_s)
49
+ when Regexp
50
+ rule.match?(message)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,4 +1,5 @@
1
- require "active_support/core_ext/kernel/singleton_class"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/module/delegation"
3
4
 
4
5
  module ActiveSupport