activesupport 5.1.7 → 7.0.4.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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +259 -585
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  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 +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +50 -43
  12. data/lib/active_support/cache/mem_cache_store.rb +194 -67
  13. data/lib/active_support/cache/memory_store.rb +70 -34
  14. data/lib/active_support/cache/null_store.rb +18 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +474 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +73 -50
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +556 -220
  19. data/lib/active_support/callbacks.rb +264 -159
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +81 -8
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  23. data/lib/active_support/concurrency/share_lock.rb +4 -3
  24. data/lib/active_support/configurable.rb +17 -16
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +18 -8
  27. data/lib/active_support/core_ext/array/conversions.rb +20 -17
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +8 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +4 -2
  33. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  34. data/lib/active_support/core_ext/array.rb +4 -1
  35. data/lib/active_support/core_ext/benchmark.rb +4 -2
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
  37. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  38. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  40. data/lib/active_support/core_ext/class/subclasses.rb +10 -24
  41. data/lib/active_support/core_ext/class.rb +2 -0
  42. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  43. data/lib/active_support/core_ext/date/blank.rb +3 -1
  44. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  45. data/lib/active_support/core_ext/date/conversions.rb +24 -22
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +2 -0
  48. data/lib/active_support/core_ext/date.rb +3 -0
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  54. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  56. data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +3 -0
  59. data/lib/active_support/core_ext/digest/uuid.rb +42 -14
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +244 -72
  62. data/lib/active_support/core_ext/file/atomic.rb +6 -2
  63. data/lib/active_support/core_ext/file.rb +2 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +7 -6
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +4 -2
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +4 -31
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  72. data/lib/active_support/core_ext/hash.rb +3 -2
  73. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +7 -14
  76. data/lib/active_support/core_ext/integer.rb +2 -0
  77. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
  80. data/lib/active_support/core_ext/kernel.rb +2 -1
  81. data/lib/active_support/core_ext/load_error.rb +3 -8
  82. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  84. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
  87. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  88. data/lib/active_support/core_ext/module/delegation.rb +97 -58
  89. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  90. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  93. data/lib/active_support/core_ext/module.rb +3 -1
  94. data/lib/active_support/core_ext/name_error.rb +30 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  99. data/lib/active_support/core_ext/numeric.rb +3 -1
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +15 -5
  102. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  103. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  104. data/lib/active_support/core_ext/object/duplicable.rb +16 -110
  105. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  106. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  107. data/lib/active_support/core_ext/object/json.rb +51 -26
  108. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  109. data/lib/active_support/core_ext/object/to_query.rb +4 -2
  110. data/lib/active_support/core_ext/object/try.rb +26 -14
  111. data/lib/active_support/core_ext/object/with_options.rb +24 -3
  112. data/lib/active_support/core_ext/object.rb +2 -0
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +6 -3
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +3 -1
  121. data/lib/active_support/core_ext/range.rb +4 -1
  122. data/lib/active_support/core_ext/regexp.rb +10 -5
  123. data/lib/active_support/core_ext/securerandom.rb +25 -3
  124. data/lib/active_support/core_ext/string/access.rb +7 -16
  125. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  126. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  127. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  128. data/lib/active_support/core_ext/string/filters.rb +44 -1
  129. data/lib/active_support/core_ext/string/indent.rb +2 -0
  130. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  133. data/lib/active_support/core_ext/string/output_safety.rb +135 -27
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +5 -1
  136. data/lib/active_support/core_ext/string/zones.rb +2 -0
  137. data/lib/active_support/core_ext/string.rb +2 -0
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  141. data/lib/active_support/core_ext/time/calculations.rb +81 -24
  142. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  143. data/lib/active_support/core_ext/time/conversions.rb +17 -12
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +12 -25
  146. data/lib/active_support/core_ext/time.rb +3 -0
  147. data/lib/active_support/core_ext/uri.rb +4 -23
  148. data/lib/active_support/core_ext.rb +4 -1
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +2 -0
  152. data/lib/active_support/dependencies/interlock.rb +12 -18
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +59 -715
  155. data/lib/active_support/deprecation/behaviors.rb +48 -13
  156. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  159. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
  161. data/lib/active_support/deprecation/reporting.rb +54 -9
  162. data/lib/active_support/deprecation.rb +10 -3
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +9 -9
  166. data/lib/active_support/duration/iso8601_serializer.rb +29 -15
  167. data/lib/active_support/duration.rb +158 -72
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +129 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +87 -122
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +46 -21
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +2 -0
  178. data/lib/active_support/file_update_checker.rb +2 -1
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +7 -5
  181. data/lib/active_support/gzip.rb +2 -0
  182. data/lib/active_support/hash_with_indifferent_access.rb +126 -42
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +5 -1
  185. data/lib/active_support/i18n_railtie.rb +19 -14
  186. data/lib/active_support/inflections.rb +2 -0
  187. data/lib/active_support/inflector/inflections.rb +41 -14
  188. data/lib/active_support/inflector/methods.rb +73 -87
  189. data/lib/active_support/inflector/transliterate.rb +56 -18
  190. data/lib/active_support/inflector.rb +2 -0
  191. data/lib/active_support/isolated_execution_state.rb +72 -0
  192. data/lib/active_support/json/decoding.rb +27 -26
  193. data/lib/active_support/json/encoding.rb +16 -6
  194. data/lib/active_support/json.rb +2 -0
  195. data/lib/active_support/key_generator.rb +25 -38
  196. data/lib/active_support/lazy_load_hooks.rb +35 -6
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +8 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +4 -2
  200. data/lib/active_support/log_subscriber.rb +54 -13
  201. data/lib/active_support/logger.rb +4 -17
  202. data/lib/active_support/logger_silence.rb +13 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +48 -10
  204. data/lib/active_support/message_encryptor.rb +111 -37
  205. data/lib/active_support/message_verifier.rb +124 -21
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +19 -76
  210. data/lib/active_support/multibyte/unicode.rb +9 -331
  211. data/lib/active_support/multibyte.rb +3 -1
  212. data/lib/active_support/notifications/fanout.rb +165 -37
  213. data/lib/active_support/notifications/instrumenter.rb +92 -11
  214. data/lib/active_support/notifications.rb +96 -30
  215. data/lib/active_support/number_helper/number_converter.rb +8 -9
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  223. data/lib/active_support/number_helper/rounding_helper.rb +16 -34
  224. data/lib/active_support/number_helper.rb +38 -12
  225. data/lib/active_support/option_merger.rb +19 -6
  226. data/lib/active_support/ordered_hash.rb +4 -2
  227. data/lib/active_support/ordered_options.rb +18 -6
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +8 -1
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +3 -10
  232. data/lib/active_support/railtie.rb +112 -11
  233. data/lib/active_support/reloader.rb +12 -11
  234. data/lib/active_support/rescuable.rb +19 -18
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +26 -15
  238. data/lib/active_support/string_inquirer.rb +4 -3
  239. data/lib/active_support/subscriber.rb +81 -42
  240. data/lib/active_support/tagged_logging.rb +45 -9
  241. data/lib/active_support/test_case.rb +86 -2
  242. data/lib/active_support/testing/assertions.rb +89 -21
  243. data/lib/active_support/testing/autorun.rb +2 -0
  244. data/lib/active_support/testing/constant_lookup.rb +2 -0
  245. data/lib/active_support/testing/declarative.rb +2 -0
  246. data/lib/active_support/testing/deprecation.rb +54 -2
  247. data/lib/active_support/testing/file_fixtures.rb +4 -0
  248. data/lib/active_support/testing/isolation.rb +6 -4
  249. data/lib/active_support/testing/method_call_assertions.rb +34 -5
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  255. data/lib/active_support/testing/stream.rb +6 -7
  256. data/lib/active_support/testing/tagged_logging.rb +3 -1
  257. data/lib/active_support/testing/time_helpers.rb +91 -15
  258. data/lib/active_support/time.rb +2 -0
  259. data/lib/active_support/time_with_zone.rb +168 -56
  260. data/lib/active_support/values/time_zone.rb +85 -37
  261. data/lib/active_support/version.rb +3 -1
  262. data/lib/active_support/xml_mini/jdom.rb +6 -5
  263. data/lib/active_support/xml_mini/libxml.rb +9 -7
  264. data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
  265. data/lib/active_support/xml_mini/nokogiri.rb +8 -6
  266. data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
  267. data/lib/active_support/xml_mini/rexml.rb +13 -4
  268. data/lib/active_support/xml_mini.rb +10 -15
  269. data/lib/active_support.rb +30 -9
  270. metadata +76 -35
  271. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  272. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  273. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  274. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  275. data/lib/active_support/core_ext/marshal.rb +0 -22
  276. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  277. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  278. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  279. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ class CodeGenerator # :nodoc:
5
+ class MethodSet
6
+ METHOD_CACHES = Hash.new { |h, k| h[k] = Module.new }
7
+
8
+ def initialize(namespace)
9
+ @cache = METHOD_CACHES[namespace]
10
+ @sources = []
11
+ @methods = {}
12
+ end
13
+
14
+ def define_cached_method(name, as: name)
15
+ name = name.to_sym
16
+ as = as.to_sym
17
+ @methods.fetch(name) do
18
+ unless @cache.method_defined?(as)
19
+ yield @sources
20
+ end
21
+ @methods[name] = as
22
+ end
23
+ end
24
+
25
+ def apply(owner, path, line)
26
+ unless @sources.empty?
27
+ @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
28
+ end
29
+ @methods.each do |name, as|
30
+ owner.define_method(name, @cache.instance_method(as))
31
+ end
32
+ end
33
+ end
34
+
35
+ class << self
36
+ def batch(owner, path, line)
37
+ if owner.is_a?(CodeGenerator)
38
+ yield owner
39
+ else
40
+ instance = new(owner, path, line)
41
+ result = yield instance
42
+ instance.execute
43
+ result
44
+ end
45
+ end
46
+ end
47
+
48
+ def initialize(owner, path, line)
49
+ @owner = owner
50
+ @path = path
51
+ @line = line
52
+ @namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) }
53
+ end
54
+
55
+ def define_cached_method(name, namespace:, as: name, &block)
56
+ @namespaces[namespace].define_cached_method(name, as: as, &block)
57
+ end
58
+
59
+ def execute
60
+ @namespaces.each_value do |method_set|
61
+ method_set.apply(@owner, @path, @line - 1)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -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,21 +99,35 @@ 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
- class MultipleIncludedBlocks < StandardError #:nodoc:
111
+ class MultipleIncludedBlocks < StandardError # :nodoc:
102
112
  def initialize
103
113
  super "Cannot define multiple 'included' blocks for a Concern"
104
114
  end
105
115
  end
106
116
 
107
- def self.extended(base) #:nodoc:
117
+ class MultiplePrependBlocks < StandardError # :nodoc:
118
+ def initialize
119
+ super "Cannot define multiple 'prepended' blocks for a Concern"
120
+ end
121
+ end
122
+
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) :
@@ -7,11 +7,27 @@ module ActiveSupport
7
7
  # A monitor that will permit dependency loading while blocked waiting for
8
8
  # the lock.
9
9
  class LoadInterlockAwareMonitor < Monitor
10
+ EXCEPTION_NEVER = { Exception => :never }.freeze
11
+ EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
12
+ private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
13
+
10
14
  # Enters an exclusive section, but allows dependency loading while blocked
11
15
  def mon_enter
12
16
  mon_try_enter ||
13
17
  ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
14
18
  end
19
+
20
+ def synchronize(&block)
21
+ Thread.handle_interrupt(EXCEPTION_NEVER) do
22
+ mon_enter
23
+
24
+ begin
25
+ Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
26
+ ensure
27
+ mon_exit
28
+ end
29
+ end
30
+ end
15
31
  end
16
32
  end
17
33
  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) ||
@@ -214,9 +215,9 @@ module ActiveSupport
214
215
  @waiting.any? { |t, (p, _)| compatible.include?(p) && @waiting.all? { |t2, (_, c2)| t == t2 || c2.include?(p) } }
215
216
  end
216
217
 
217
- def wait_for(method)
218
+ def wait_for(method, &block)
218
219
  @sleeping[Thread.current] = method
219
- @cv.wait_while { yield }
220
+ @cv.wait_while(&block)
220
221
  ensure
221
222
  @sleeping.delete Thread.current
222
223
  end
@@ -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 OrderedOptions.
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
@@ -94,19 +94,19 @@ module ActiveSupport
94
94
  # User.new.allowed_access = true # => NoMethodError
95
95
  # User.new.allowed_access # => NoMethodError
96
96
  #
97
- # Also you can pass a block to set up the attribute with a default value.
97
+ # Also you can pass <tt>default</tt> or a block to set up the attribute with a default value.
98
98
  #
99
99
  # class User
100
100
  # include ActiveSupport::Configurable
101
+ # config_accessor :allowed_access, default: false
101
102
  # config_accessor :hair_colors do
102
103
  # [:brown, :black, :blonde, :red]
103
104
  # end
104
105
  # end
105
106
  #
107
+ # User.allowed_access # => false
106
108
  # User.hair_colors # => [:brown, :black, :blonde, :red]
107
- def config_accessor(*names)
108
- options = names.extract_options!
109
-
109
+ def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
110
110
  names.each do |name|
111
111
  raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
112
112
 
@@ -116,19 +116,20 @@ module ActiveSupport
116
116
  singleton_class.class_eval reader, __FILE__, reader_line
117
117
  singleton_class.class_eval writer, __FILE__, writer_line
118
118
 
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
119
+ if instance_accessor
120
+ class_eval reader, __FILE__, reader_line if instance_reader
121
+ class_eval writer, __FILE__, writer_line if instance_writer
122
122
  end
123
- send("#{name}=", yield) if block_given?
123
+
124
+ send("#{name}=", block_given? ? yield : default)
124
125
  end
125
126
  end
126
127
  private :config_accessor
127
128
  end
128
129
 
129
- # Reads and writes attributes from a configuration <tt>OrderedHash</tt>.
130
+ # Reads and writes attributes from a configuration OrderedOptions.
130
131
  #
131
- # require 'active_support/configurable'
132
+ # require "active_support/configurable"
132
133
  #
133
134
  # class User
134
135
  # include ActiveSupport::Configurable
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Reads a YAML configuration file, evaluating any ERB, then
5
+ # parsing the resulting YAML.
6
+ #
7
+ # Warns in case of YAML confusing characters, like invisible
8
+ # non-breaking spaces.
9
+ class ConfigurationFile # :nodoc:
10
+ class FormatError < StandardError; end
11
+
12
+ def initialize(content_path)
13
+ @content_path = content_path.to_s
14
+ @content = read content_path
15
+ end
16
+
17
+ def self.parse(content_path, **options)
18
+ new(content_path).parse(**options)
19
+ end
20
+
21
+ def parse(context: nil, **options)
22
+ source = render(context)
23
+ if YAML.respond_to?(:unsafe_load)
24
+ YAML.unsafe_load(source, **options) || {}
25
+ else
26
+ YAML.load(source, **options) || {}
27
+ end
28
+ rescue Psych::SyntaxError => error
29
+ raise "YAML syntax error occurred while parsing #{@content_path}. " \
30
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
31
+ "Error: #{error.message}"
32
+ end
33
+
34
+ private
35
+ def read(content_path)
36
+ require "yaml"
37
+ require "erb"
38
+
39
+ File.read(content_path).tap do |content|
40
+ if content.include?("\u00A0")
41
+ warn "#{content_path} contains invisible non-breaking spaces, you may want to remove those"
42
+ end
43
+ end
44
+ end
45
+
46
+ def render(context)
47
+ erb = ERB.new(@content).tap { |e| e.filename = @content_path }
48
+ context ? erb.result(context) : erb.result
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Returns the tail of the array from +position+.
3
5
  #
@@ -27,17 +29,25 @@ class Array
27
29
  end
28
30
  end
29
31
 
30
- # Returns a copy of the Array without the specified elements.
32
+ # Returns a new array that includes the passed elements.
33
+ #
34
+ # [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
35
+ # [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
36
+ def including(*elements)
37
+ self + elements.flatten(1)
38
+ end
39
+
40
+ # Returns a copy of the Array excluding the specified elements.
31
41
  #
32
- # people = ["David", "Rafael", "Aaron", "Todd"]
33
- # people.without "Aaron", "Todd"
34
- # # => ["David", "Rafael"]
42
+ # ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
43
+ # [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
35
44
  #
36
- # Note: This is an optimization of `Enumerable#without` that uses `Array#-`
37
- # instead of `Array#reject` for performance reasons.
38
- def without(*elements)
39
- self - elements
45
+ # Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
46
+ # instead of <tt>Array#reject</tt> for performance reasons.
47
+ def excluding(*elements)
48
+ self - elements.flatten(1)
40
49
  end
50
+ alias :without :excluding
41
51
 
42
52
  # Equal to <tt>self[1]</tt>.
43
53
  #
@@ -1,4 +1,5 @@
1
- require "active_support/xml_mini"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/hash/keys"
3
4
  require "active_support/core_ext/string/inflections"
4
5
  require "active_support/core_ext/object/to_param"
@@ -14,12 +15,12 @@ class Array
14
15
  #
15
16
  # ==== Options
16
17
  #
17
- # * <tt>:words_connector</tt> - The sign or word used to join the elements
18
- # in arrays with two or more elements (default: ", ").
19
- # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
20
- # in arrays with two elements (default: " and ").
18
+ # * <tt>:words_connector</tt> - The sign or word used to join all but the last
19
+ # element in arrays with three or more elements (default: ", ").
21
20
  # * <tt>:last_word_connector</tt> - The sign or word used to join the last element
22
21
  # in arrays with three or more elements (default: ", and ").
22
+ # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
23
+ # in arrays with two elements (default: " and ").
23
24
  # * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
24
25
  # the connector options defined on the 'support.array' namespace in the
25
26
  # corresponding dictionary file.
@@ -64,7 +65,7 @@ class Array
64
65
  two_words_connector: " and ",
65
66
  last_word_connector: ", and "
66
67
  }
67
- if defined?(I18n)
68
+ if options[:locale] != false && defined?(I18n)
68
69
  i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
69
70
  default_connectors.merge!(i18n_connectors)
70
71
  end
@@ -72,23 +73,25 @@ class Array
72
73
 
73
74
  case length
74
75
  when 0
75
- ""
76
+ +""
76
77
  when 1
77
- "#{self[0]}"
78
+ +"#{self[0]}"
78
79
  when 2
79
- "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
80
+ +"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
80
81
  else
81
- "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
82
+ +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
82
83
  end
83
84
  end
84
85
 
85
86
  # Extends <tt>Array#to_s</tt> to convert a collection of elements into a
86
87
  # comma separated id list if <tt>:db</tt> argument is given as the format.
87
88
  #
88
- # Blog.all.to_formatted_s(:db) # => "1,2,3"
89
- # Blog.none.to_formatted_s(:db) # => "null"
90
- # [1,2].to_formatted_s # => "[1, 2]"
91
- def to_formatted_s(format = :default)
89
+ # This method is aliased to <tt>to_formatted_s</tt>.
90
+ #
91
+ # Blog.all.to_fs(:db) # => "1,2,3"
92
+ # Blog.none.to_fs(:db) # => "null"
93
+ # [1,2].to_fs # => "[1, 2]"
94
+ def to_fs(format = :default)
92
95
  case format
93
96
  when :db
94
97
  if empty?
@@ -100,8 +103,8 @@ class Array
100
103
  to_default_s
101
104
  end
102
105
  end
106
+ alias_method :to_formatted_s, :to_fs
103
107
  alias_method :to_default_s, :to_s
104
- alias_method :to_s, :to_formatted_s
105
108
 
106
109
  # Returns a string that represents the array in XML by invoking +to_xml+
107
110
  # on each element. Active Record collections delegate their representation
@@ -179,13 +182,13 @@ class Array
179
182
  # </messages>
180
183
  #
181
184
  def to_xml(options = {})
182
- require "active_support/builder" unless defined?(Builder)
185
+ require "active_support/builder" unless defined?(Builder::XmlMarkup)
183
186
 
184
187
  options = options.dup
185
188
  options[:indent] ||= 2
186
189
  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
187
190
  options[:root] ||= \
188
- if first.class != Hash && all? { |e| e.is_a?(first.class) }
191
+ if first.class != Hash && all?(first.class)
189
192
  underscored = ActiveSupport::Inflector.underscore(first.class.name)
190
193
  ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
191
194
  else
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ NOT_SET = Object.new # :nodoc:
5
+ def to_s(format = NOT_SET) # :nodoc:
6
+ case format
7
+ when :db
8
+ ActiveSupport::Deprecation.warn(
9
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
10
+ )
11
+ if empty?
12
+ "null"
13
+ else
14
+ collect(&:id).join(",")
15
+ end
16
+ when NOT_SET
17
+ to_default_s
18
+ else
19
+ ActiveSupport::Deprecation.warn(
20
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
21
+ )
22
+ to_default_s
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Removes and returns the elements for which the block returns a true value.
5
+ # If no block is given, an Enumerator is returned instead.
6
+ #
7
+ # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8
+ # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
9
+ # numbers # => [0, 2, 4, 6, 8]
10
+ def extract!
11
+ return to_enum(:extract!) { size } unless block_given?
12
+
13
+ extracted_elements = []
14
+
15
+ reject! do |element|
16
+ extracted_elements << element if yield(element)
17
+ end
18
+
19
+ extracted_elements
20
+ end
21
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Hash
2
4
  # By default, only instances of Hash itself are extractable.
3
5
  # Subclasses of Hash may implement this method and return
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Splits or iterates over the array in groups of size +number+,
3
5
  # padding any remaining slots with +fill_with+ unless it is +false+.
@@ -17,7 +19,7 @@ class Array
17
19
  # ["1", "2"]
18
20
  # ["3", "4"]
19
21
  # ["5"]
20
- def in_groups_of(number, fill_with = nil)
22
+ def in_groups_of(number, fill_with = nil, &block)
21
23
  if number.to_i <= 0
22
24
  raise ArgumentError,
23
25
  "Group size must be a positive integer, was #{number.inspect}"
@@ -34,7 +36,7 @@ class Array
34
36
  end
35
37
 
36
38
  if block_given?
37
- collection.each_slice(number) { |slice| yield(slice) }
39
+ collection.each_slice(number, &block)
38
40
  else
39
41
  collection.each_slice(number).to_a
40
42
  end
@@ -57,7 +59,7 @@ class Array
57
59
  # ["1", "2", "3"]
58
60
  # ["4", "5"]
59
61
  # ["6", "7"]
60
- def in_groups(number, fill_with = nil)
62
+ def in_groups(number, fill_with = nil, &block)
61
63
  # size.div number gives minor group size;
62
64
  # size % number gives how many objects need extra accommodation;
63
65
  # each group hold either division or division + 1 items.
@@ -77,7 +79,7 @@ class Array
77
79
  end
78
80
 
79
81
  if block_given?
80
- groups.each { |g| yield(g) }
82
+ groups.each(&block)
81
83
  else
82
84
  groups
83
85
  end
@@ -88,11 +90,11 @@ class Array
88
90
  #
89
91
  # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
90
92
  # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
91
- def split(value = nil)
93
+ def split(value = nil, &block)
92
94
  arr = dup
93
95
  result = []
94
96
  if block_given?
95
- while (idx = arr.index { |i| yield i })
97
+ while (idx = arr.index(&block))
96
98
  result << arr.shift(idx)
97
99
  arr.shift
98
100
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/array_inquirer"
2
4
 
3
5
  class Array
4
- # Wraps the array in an +ArrayInquirer+ object, which gives a friendlier way
5
- # to check its string-like contents.
6
+ # Wraps the array in an ActiveSupport::ArrayInquirer object, which gives a
7
+ # friendlier way to check its string-like contents.
6
8
  #
7
9
  # pets = [:cat, :dog].inquiry
8
10
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Wraps its argument in an array unless it is already an array (or array-like).
3
5
  #
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/array/wrap"
2
4
  require "active_support/core_ext/array/access"
3
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
+ require "active_support/core_ext/array/extract"
4
8
  require "active_support/core_ext/array/extract_options"
5
9
  require "active_support/core_ext/array/grouping"
6
- require "active_support/core_ext/array/prepend_and_append"
7
10
  require "active_support/core_ext/array/inquiry"