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,11 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/descendants_tracker"
3
5
  require "active_support/core_ext/array/extract_options"
4
6
  require "active_support/core_ext/class/attribute"
5
- require "active_support/core_ext/kernel/reporting"
6
- require "active_support/core_ext/kernel/singleton_class"
7
7
  require "active_support/core_ext/string/filters"
8
- require "active_support/deprecation"
9
8
  require "thread"
10
9
 
11
10
  module ActiveSupport
@@ -21,6 +20,9 @@ module ActiveSupport
21
20
  # +ClassMethods.set_callback+), and run the installed callbacks at the
22
21
  # appropriate times (via +run_callbacks+).
23
22
  #
23
+ # By default callbacks are halted by throwing +:abort+.
24
+ # See +ClassMethods.define_callbacks+ for details.
25
+ #
24
26
  # Three kinds of callbacks are supported: before callbacks, run before a
25
27
  # certain event; after callbacks, run after the event; and around callbacks,
26
28
  # blocks that surround the event, triggering it when they yield. Callback code
@@ -62,8 +64,7 @@ module ActiveSupport
62
64
 
63
65
  included do
64
66
  extend ActiveSupport::DescendantsTracker
65
- class_attribute :__callbacks, instance_writer: false
66
- self.__callbacks ||= {}
67
+ class_attribute :__callbacks, instance_writer: false, default: {}
67
68
  end
68
69
 
69
70
  CALLBACK_FILTER_TYPES = [:before, :after, :around]
@@ -99,32 +100,6 @@ module ActiveSupport
99
100
  env = Filters::Environment.new(self, false, nil)
100
101
  next_sequence = callbacks.compile
101
102
 
102
- invoke_sequence = Proc.new do
103
- skipped = nil
104
- while true
105
- current = next_sequence
106
- current.invoke_before(env)
107
- if current.final?
108
- env.value = !env.halted && (!block_given? || yield)
109
- elsif current.skip?(env)
110
- (skipped ||= []) << current
111
- next_sequence = next_sequence.nested
112
- next
113
- else
114
- next_sequence = next_sequence.nested
115
- begin
116
- target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
117
- target.send(method, *arguments, &block)
118
- ensure
119
- next_sequence = current
120
- end
121
- end
122
- current.invoke_after(env)
123
- skipped.pop.invoke_after(env) while skipped && skipped.first
124
- break env.value
125
- end
126
- end
127
-
128
103
  # Common case: no 'around' callbacks defined
129
104
  if next_sequence.final?
130
105
  next_sequence.invoke_before(env)
@@ -132,17 +107,43 @@ module ActiveSupport
132
107
  next_sequence.invoke_after(env)
133
108
  env.value
134
109
  else
110
+ invoke_sequence = Proc.new do
111
+ skipped = nil
112
+
113
+ while true
114
+ current = next_sequence
115
+ current.invoke_before(env)
116
+ if current.final?
117
+ env.value = !env.halted && (!block_given? || yield)
118
+ elsif current.skip?(env)
119
+ (skipped ||= []) << current
120
+ next_sequence = next_sequence.nested
121
+ next
122
+ else
123
+ next_sequence = next_sequence.nested
124
+ begin
125
+ target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
126
+ target.send(method, *arguments, &block)
127
+ ensure
128
+ next_sequence = current
129
+ end
130
+ end
131
+ current.invoke_after(env)
132
+ skipped.pop.invoke_after(env) while skipped&.first
133
+ break env.value
134
+ end
135
+ end
136
+
135
137
  invoke_sequence.call
136
138
  end
137
139
  end
138
140
  end
139
141
 
140
142
  private
141
-
142
143
  # A hook invoked every time a before callback is halted.
143
144
  # This can be overridden in ActiveSupport::Callbacks implementors in order
144
145
  # to provide better debugging/logging.
145
- def halted_callback_hook(filter)
146
+ def halted_callback_hook(filter, name)
146
147
  end
147
148
 
148
149
  module Conditionals # :nodoc:
@@ -158,17 +159,17 @@ module ActiveSupport
158
159
  Environment = Struct.new(:target, :halted, :value)
159
160
 
160
161
  class Before
161
- def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
162
+ def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter, name)
162
163
  halted_lambda = chain_config[:terminator]
163
164
 
164
165
  if user_conditions.any?
165
- halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
166
+ halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
166
167
  else
167
- halting(callback_sequence, user_callback, halted_lambda, filter)
168
+ halting(callback_sequence, user_callback, halted_lambda, filter, name)
168
169
  end
169
170
  end
170
171
 
171
- def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
172
+ def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
172
173
  callback_sequence.before do |env|
173
174
  target = env.target
174
175
  value = env.value
@@ -178,7 +179,7 @@ module ActiveSupport
178
179
  result_lambda = -> { user_callback.call target, value }
179
180
  env.halted = halted_lambda.call(target, result_lambda)
180
181
  if env.halted
181
- target.send :halted_callback_hook, filter
182
+ target.send :halted_callback_hook, filter, name
182
183
  end
183
184
  end
184
185
 
@@ -187,7 +188,7 @@ module ActiveSupport
187
188
  end
188
189
  private_class_method :halting_and_conditional
189
190
 
190
- def self.halting(callback_sequence, user_callback, halted_lambda, filter)
191
+ def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
191
192
  callback_sequence.before do |env|
192
193
  target = env.target
193
194
  value = env.value
@@ -196,9 +197,8 @@ module ActiveSupport
196
197
  unless halted
197
198
  result_lambda = -> { user_callback.call target, value }
198
199
  env.halted = halted_lambda.call(target, result_lambda)
199
-
200
200
  if env.halted
201
- target.send :halted_callback_hook, filter
201
+ target.send :halted_callback_hook, filter, name
202
202
  end
203
203
  end
204
204
 
@@ -297,8 +297,8 @@ module ActiveSupport
297
297
  @kind = kind
298
298
  @filter = filter
299
299
  @key = compute_identifier filter
300
- @if = Array(options[:if])
301
- @unless = Array(options[:unless])
300
+ @if = check_conditionals(options[:if])
301
+ @unless = check_conditionals(options[:unless])
302
302
  end
303
303
 
304
304
  def filter; @key; end
@@ -322,7 +322,7 @@ module ActiveSupport
322
322
 
323
323
  def duplicates?(other)
324
324
  case @filter
325
- when Symbol, String
325
+ when Symbol
326
326
  matches?(other.kind, other.filter)
327
327
  else
328
328
  false
@@ -336,7 +336,7 @@ module ActiveSupport
336
336
 
337
337
  case kind
338
338
  when :before
339
- Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter)
339
+ Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
340
340
  when :after
341
341
  Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
342
342
  when :around
@@ -349,9 +349,27 @@ module ActiveSupport
349
349
  end
350
350
 
351
351
  private
352
+ EMPTY_ARRAY = [].freeze
353
+ private_constant :EMPTY_ARRAY
354
+
355
+ def check_conditionals(conditionals)
356
+ return EMPTY_ARRAY if conditionals.blank?
357
+
358
+ conditionals = Array(conditionals)
359
+ if conditionals.any? { |c| c.is_a?(String) }
360
+ raise ArgumentError, <<-MSG.squish
361
+ Passing string to be evaluated in :if and :unless conditional
362
+ options is not supported. Pass a symbol for an instance method,
363
+ or a lambda, proc or block, instead.
364
+ MSG
365
+ end
366
+
367
+ conditionals.freeze
368
+ end
369
+
352
370
  def compute_identifier(filter)
353
371
  case filter
354
- when String, ::Proc
372
+ when ::Proc
355
373
  filter.object_id
356
374
  else
357
375
  filter
@@ -388,21 +406,17 @@ module ActiveSupport
388
406
  # The actual invocation is left up to the caller to minimize
389
407
  # call stack pollution.
390
408
  def expand(target, value, block)
391
- result = @arguments.map { |arg|
409
+ expanded = [@override_target || target, @override_block || block, @method_name]
410
+
411
+ @arguments.each do |arg|
392
412
  case arg
393
- when :value; value
394
- when :target; target
395
- when :block; block || raise(ArgumentError)
413
+ when :value then expanded << value
414
+ when :target then expanded << target
415
+ when :block then expanded << (block || raise(ArgumentError))
396
416
  end
397
- }
398
-
399
- result.unshift @method_name
400
- result.unshift @override_block || block
401
- result.unshift @override_target || target
417
+ end
402
418
 
403
- # target, block, method, *arguments = result
404
- # target.send(method, *arguments, &block)
405
- result
419
+ expanded
406
420
  end
407
421
 
408
422
  # Return a lambda that will make this call when given the input
@@ -426,7 +440,6 @@ module ActiveSupport
426
440
  # Filters support:
427
441
  #
428
442
  # Symbols:: A method to call.
429
- # Strings:: Some content to evaluate.
430
443
  # Procs:: A proc to call with the object.
431
444
  # Objects:: An object with a <tt>before_foo</tt> method on it to call.
432
445
  #
@@ -436,8 +449,6 @@ module ActiveSupport
436
449
  case filter
437
450
  when Symbol
438
451
  new(nil, filter, [], nil)
439
- when String
440
- new(nil, :instance_exec, [:value], compile_lambda(filter))
441
452
  when Conditionals::Value
442
453
  new(filter, :call, [:target, :value], nil)
443
454
  when ::Proc
@@ -454,10 +465,6 @@ module ActiveSupport
454
465
  new(filter, method_to_call, [:target], nil)
455
466
  end
456
467
  end
457
-
458
- def self.compile_lambda(filter)
459
- eval("lambda { |value| #{filter} }")
460
- end
461
468
  end
462
469
 
463
470
  # Execute before and after filters in a sequence instead of
@@ -491,9 +498,7 @@ module ActiveSupport
491
498
  arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
492
499
  end
493
500
 
494
- def nested
495
- @nested
496
- end
501
+ attr_reader :nested
497
502
 
498
503
  def final?
499
504
  !@call_template
@@ -512,7 +517,6 @@ module ActiveSupport
512
517
  end
513
518
  end
514
519
 
515
- # An Array with a compile method.
516
520
  class CallbackChain #:nodoc:#
517
521
  include Enumerable
518
522
 
@@ -573,10 +577,9 @@ module ActiveSupport
573
577
  end
574
578
 
575
579
  protected
576
- def chain; @chain; end
580
+ attr_reader :chain
577
581
 
578
582
  private
579
-
580
583
  def append_one(callback)
581
584
  @callbacks = nil
582
585
  remove_duplicates(callback)
@@ -598,7 +601,7 @@ module ActiveSupport
598
601
  Proc.new do |target, result_lambda|
599
602
  terminate = true
600
603
  catch(:abort) do
601
- result_lambda.call if result_lambda.is_a?(Proc)
604
+ result_lambda.call
602
605
  terminate = false
603
606
  end
604
607
  terminate
@@ -651,24 +654,25 @@ module ActiveSupport
651
654
  #
652
655
  # ===== Options
653
656
  #
654
- # * <tt>:if</tt> - A symbol, a string (deprecated) or an array of symbols,
655
- # each naming an instance method or a proc; the callback will be called
656
- # only when they all return a true value.
657
- # * <tt>:unless</tt> - A symbol, a string (deprecated) or an array of symbols,
658
- # each naming an instance method or a proc; the callback will be called
659
- # only when they all return a false value.
657
+ # * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance
658
+ # method or a proc; the callback will be called only when they all return
659
+ # a true value.
660
+ #
661
+ # If a proc is given, its body is evaluated in the context of the
662
+ # current object. It can also optionally accept the current object as
663
+ # an argument.
664
+ # * <tt>:unless</tt> - A symbol or an array of symbols, each naming an
665
+ # instance method or a proc; the callback will be called only when they
666
+ # all return a false value.
667
+ #
668
+ # If a proc is given, its body is evaluated in the context of the
669
+ # current object. It can also optionally accept the current object as
670
+ # an argument.
660
671
  # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
661
672
  # existing chain rather than appended.
662
673
  def set_callback(name, *filter_list, &block)
663
674
  type, filters, options = normalize_callback_params(filter_list, block)
664
675
 
665
- if options[:if].is_a?(String) || options[:unless].is_a?(String)
666
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
667
- Passing string to :if and :unless conditional options is deprecated
668
- and will be removed in Rails 5.2 without replacement.
669
- MSG
670
- end
671
-
672
676
  self_chain = get_callbacks name
673
677
  mapped = filters.map do |filter|
674
678
  Callback.build(self_chain, filter, type, options)
@@ -693,13 +697,6 @@ module ActiveSupport
693
697
  def skip_callback(name, *filter_list, &block)
694
698
  type, filters, options = normalize_callback_params(filter_list, block)
695
699
 
696
- if options[:if].is_a?(String) || options[:unless].is_a?(String)
697
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
698
- Passing string to :if and :unless conditional options is deprecated
699
- and will be removed in Rails 5.2 without replacement.
700
- MSG
701
- end
702
-
703
700
  options[:raise] = true unless options.key?(:raise)
704
701
 
705
702
  __update_callbacks(name) do |target, chain|
@@ -758,8 +755,8 @@ module ActiveSupport
758
755
  # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
759
756
  # callbacks should be terminated by the <tt>:terminator</tt> option. By
760
757
  # default after callbacks are executed no matter if callback chain was
761
- # terminated or not. This option makes sense only when <tt>:terminator</tt>
762
- # option is specified.
758
+ # terminated or not. This option has no effect if <tt>:terminator</tt>
759
+ # option is set to +nil+.
763
760
  #
764
761
  # * <tt>:scope</tt> - Indicates which methods should be executed when an
765
762
  # object is used as a callback.
@@ -818,7 +815,9 @@ module ActiveSupport
818
815
  names.each do |name|
819
816
  name = name.to_sym
820
817
 
821
- set_callbacks name, CallbackChain.new(name, options)
818
+ ([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
819
+ target.set_callbacks name, CallbackChain.new(name, options)
820
+ end
822
821
 
823
822
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
824
823
  def _run_#{name}_callbacks(&block)
@@ -841,13 +840,22 @@ module ActiveSupport
841
840
  end
842
841
 
843
842
  protected
844
-
845
843
  def get_callbacks(name) # :nodoc:
846
844
  __callbacks[name.to_sym]
847
845
  end
848
846
 
849
- def set_callbacks(name, callbacks) # :nodoc:
850
- self.__callbacks = __callbacks.merge(name.to_sym => callbacks)
847
+ if Module.instance_method(:method_defined?).arity == 1 # Ruby 2.5 and older
848
+ def set_callbacks(name, callbacks) # :nodoc:
849
+ self.__callbacks = __callbacks.merge(name.to_sym => callbacks)
850
+ end
851
+ else # Ruby 2.6 and newer
852
+ def set_callbacks(name, callbacks) # :nodoc:
853
+ unless singleton_class.method_defined?(:__callbacks, false)
854
+ self.__callbacks = __callbacks.dup
855
+ end
856
+ self.__callbacks[name.to_sym] = callbacks
857
+ self.__callbacks
858
+ end
851
859
  end
852
860
  end
853
861
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # A typical module looks like this:
3
5
  #
@@ -17,7 +19,7 @@ module ActiveSupport
17
19
  # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
18
20
  # written as:
19
21
  #
20
- # require 'active_support/concern'
22
+ # require "active_support/concern"
21
23
  #
22
24
  # module M
23
25
  # extend ActiveSupport::Concern
@@ -74,7 +76,7 @@ module ActiveSupport
74
76
  # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
75
77
  # module dependencies are properly resolved:
76
78
  #
77
- # require 'active_support/concern'
79
+ # require "active_support/concern"
78
80
  #
79
81
  # module Foo
80
82
  # extend ActiveSupport::Concern
@@ -97,6 +99,14 @@ module ActiveSupport
97
99
  # class Host
98
100
  # include Bar # It works, now Bar takes care of its dependencies
99
101
  # end
102
+ #
103
+ # === Prepending concerns
104
+ #
105
+ # Just like <tt>include</tt>, concerns also support <tt>prepend</tt> with a corresponding
106
+ # <tt>prepended do</tt> callback. <tt>module ClassMethods</tt> or <tt>class_methods do</tt> are
107
+ # prepended as well.
108
+ #
109
+ # <tt>prepend</tt> is also used for any dependencies.
100
110
  module Concern
101
111
  class MultipleIncludedBlocks < StandardError #:nodoc:
102
112
  def initialize
@@ -104,14 +114,20 @@ module ActiveSupport
104
114
  end
105
115
  end
106
116
 
117
+ class MultiplePrependBlocks < StandardError #:nodoc:
118
+ def initialize
119
+ super "Cannot define multiple 'prepended' blocks for a Concern"
120
+ end
121
+ end
122
+
107
123
  def self.extended(base) #:nodoc:
108
124
  base.instance_variable_set(:@_dependencies, [])
109
125
  end
110
126
 
111
- def append_features(base)
127
+ def append_features(base) #:nodoc:
112
128
  if base.instance_variable_defined?(:@_dependencies)
113
129
  base.instance_variable_get(:@_dependencies) << self
114
- return false
130
+ false
115
131
  else
116
132
  return false if base < self
117
133
  @_dependencies.each { |dep| base.include(dep) }
@@ -121,16 +137,73 @@ module ActiveSupport
121
137
  end
122
138
  end
123
139
 
140
+ def prepend_features(base) #:nodoc:
141
+ if base.instance_variable_defined?(:@_dependencies)
142
+ base.instance_variable_get(:@_dependencies).unshift self
143
+ false
144
+ else
145
+ return false if base < self
146
+ @_dependencies.each { |dep| base.prepend(dep) }
147
+ super
148
+ base.singleton_class.prepend const_get(:ClassMethods) if const_defined?(:ClassMethods)
149
+ base.class_eval(&@_prepended_block) if instance_variable_defined?(:@_prepended_block)
150
+ end
151
+ end
152
+
153
+ # Evaluate given block in context of base class,
154
+ # so that you can write class macros here.
155
+ # When you define more than one +included+ block, it raises an exception.
124
156
  def included(base = nil, &block)
125
157
  if base.nil?
126
- raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block)
158
+ if instance_variable_defined?(:@_included_block)
159
+ if @_included_block.source_location != block.source_location
160
+ raise MultipleIncludedBlocks
161
+ end
162
+ else
163
+ @_included_block = block
164
+ end
165
+ else
166
+ super
167
+ end
168
+ end
127
169
 
128
- @_included_block = block
170
+ # Evaluate given block in context of base class,
171
+ # so that you can write class macros here.
172
+ # When you define more than one +prepended+ block, it raises an exception.
173
+ def prepended(base = nil, &block)
174
+ if base.nil?
175
+ if instance_variable_defined?(:@_prepended_block)
176
+ if @_prepended_block.source_location != block.source_location
177
+ raise MultiplePrependBlocks
178
+ end
179
+ else
180
+ @_prepended_block = block
181
+ end
129
182
  else
130
183
  super
131
184
  end
132
185
  end
133
186
 
187
+ # Define class methods from given block.
188
+ # You can define private class methods as well.
189
+ #
190
+ # module Example
191
+ # extend ActiveSupport::Concern
192
+ #
193
+ # class_methods do
194
+ # def foo; puts 'foo'; end
195
+ #
196
+ # private
197
+ # def bar; puts 'bar'; end
198
+ # end
199
+ # end
200
+ #
201
+ # class Buzz
202
+ # include Example
203
+ # end
204
+ #
205
+ # Buzz.foo # => "foo"
206
+ # Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError)
134
207
  def class_methods(&class_methods_module_definition)
135
208
  mod = const_defined?(:ClassMethods, false) ?
136
209
  const_get(:ClassMethods) :
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+
5
+ module ActiveSupport
6
+ module Concurrency
7
+ # A monitor that will permit dependency loading while blocked waiting for
8
+ # the lock.
9
+ class LoadInterlockAwareMonitor < Monitor
10
+ EXCEPTION_NEVER = { Exception => :never }.freeze
11
+ EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
12
+ private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
13
+
14
+ # Enters an exclusive section, but allows dependency loading while blocked
15
+ def mon_enter
16
+ mon_try_enter ||
17
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
18
+ end
19
+
20
+ def synchronize
21
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
22
+ mon_enter
23
+
24
+ begin
25
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
26
+ yield
27
+ end
28
+ ensure
29
+ mon_exit
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "thread"
2
4
  require "monitor"
3
5
 
@@ -198,7 +200,6 @@ module ActiveSupport
198
200
  end
199
201
 
200
202
  private
201
-
202
203
  # Must be called within synchronize
203
204
  def busy_for_exclusive?(purpose)
204
205
  busy_for_sharing?(purpose) ||
@@ -1,11 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/ordered_options"
3
- require "active_support/core_ext/array/extract_options"
4
- require "active_support/core_ext/regexp"
5
5
 
6
6
  module ActiveSupport
7
7
  # Configurable provides a <tt>config</tt> method to store and retrieve
8
- # configuration options as an <tt>OrderedHash</tt>.
8
+ # configuration options as an <tt>OrderedOptions</tt>.
9
9
  module Configurable
10
10
  extend ActiveSupport::Concern
11
11
 
@@ -67,8 +67,8 @@ module ActiveSupport
67
67
  # end
68
68
  # # => NameError: invalid config attribute name
69
69
  #
70
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
71
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
70
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
71
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
72
72
  #
73
73
  # class User
74
74
  # include ActiveSupport::Configurable
@@ -81,7 +81,7 @@ module ActiveSupport
81
81
  # User.new.allowed_access = true # => NoMethodError
82
82
  # User.new.allowed_access # => NoMethodError
83
83
  #
84
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
84
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
85
85
  #
86
86
  # class User
87
87
  # include ActiveSupport::Configurable
@@ -104,9 +104,7 @@ module ActiveSupport
104
104
  # end
105
105
  #
106
106
  # User.hair_colors # => [:brown, :black, :blonde, :red]
107
- def config_accessor(*names)
108
- options = names.extract_options!
109
-
107
+ def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
110
108
  names.each do |name|
111
109
  raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
112
110
 
@@ -116,9 +114,9 @@ module ActiveSupport
116
114
  singleton_class.class_eval reader, __FILE__, reader_line
117
115
  singleton_class.class_eval writer, __FILE__, writer_line
118
116
 
119
- unless options[:instance_accessor] == false
120
- class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
121
- class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
117
+ if instance_accessor
118
+ class_eval reader, __FILE__, reader_line if instance_reader
119
+ class_eval writer, __FILE__, writer_line if instance_writer
122
120
  end
123
121
  send("#{name}=", yield) if block_given?
124
122
  end
@@ -126,9 +124,9 @@ module ActiveSupport
126
124
  private :config_accessor
127
125
  end
128
126
 
129
- # Reads and writes attributes from a configuration <tt>OrderedHash</tt>.
127
+ # Reads and writes attributes from a configuration <tt>OrderedOptions</tt>.
130
128
  #
131
- # require 'active_support/configurable'
129
+ # require "active_support/configurable"
132
130
  #
133
131
  # class User
134
132
  # include ActiveSupport::Configurable