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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "benchmark"
2
4
 
3
5
  class << Benchmark
@@ -8,7 +10,7 @@ class << Benchmark
8
10
  #
9
11
  # Benchmark.ms { User.all }
10
12
  # # => 0.074
11
- def ms
12
- 1000 * realtime { yield }
13
+ def ms(&block)
14
+ 1000 * realtime(&block)
13
15
  end
14
16
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bigdecimal"
2
4
  require "bigdecimal/util"
3
5
 
4
6
  module ActiveSupport
5
- module BigDecimalWithDefaultFormat #:nodoc:
7
+ module BigDecimalWithDefaultFormat # :nodoc:
6
8
  def to_s(format = "F")
7
9
  super(format)
8
10
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/big_decimal/conversions"
@@ -1,11 +1,21 @@
1
- require "active_support/core_ext/kernel/singleton_class"
2
- require "active_support/core_ext/module/remove_method"
3
- require "active_support/core_ext/array/extract_options"
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
4
 
5
5
  class Class
6
6
  # Declare a class-level attribute whose value is inheritable by subclasses.
7
7
  # Subclasses can change their own value and it will not impact parent class.
8
8
  #
9
+ # ==== Options
10
+ #
11
+ # * <tt>:instance_reader</tt> - Sets the instance reader method (defaults to true).
12
+ # * <tt>:instance_writer</tt> - Sets the instance writer method (defaults to true).
13
+ # * <tt>:instance_accessor</tt> - Sets both instance methods (defaults to true).
14
+ # * <tt>:instance_predicate</tt> - Sets a predicate method (defaults to true).
15
+ # * <tt>:default</tt> - Sets a default value for the attribute (defaults to nil).
16
+ #
17
+ # ==== Examples
18
+ #
9
19
  # class Base
10
20
  # class_attribute :setting
11
21
  # end
@@ -68,61 +78,54 @@ class Class
68
78
  # object.setting = false # => NoMethodError
69
79
  #
70
80
  # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
71
- def class_attribute(*attrs)
72
- options = attrs.extract_options!
73
- instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
74
- instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
75
- instance_predicate = options.fetch(:instance_predicate, true)
81
+ #
82
+ # To set a default value for the attribute, pass <tt>default:</tt>, like so:
83
+ #
84
+ # class_attribute :settings, default: {}
85
+ def class_attribute(*attrs, instance_accessor: true,
86
+ instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
76
87
 
88
+ class_methods, methods = [], []
77
89
  attrs.each do |name|
78
- remove_possible_singleton_method(name)
79
- define_singleton_method(name) { nil }
80
-
81
- remove_possible_singleton_method("#{name}?")
82
- define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
83
-
84
- ivar = "@#{name}"
90
+ unless name.is_a?(Symbol) || name.is_a?(String)
91
+ raise TypeError, "#{name.inspect} is not a symbol nor a string"
92
+ end
85
93
 
86
- remove_possible_singleton_method("#{name}=")
87
- define_singleton_method("#{name}=") do |val|
88
- singleton_class.class_eval do
89
- remove_possible_method(name)
90
- define_method(name) { val }
94
+ class_methods << <<~RUBY # In case the method exists and is not public
95
+ silence_redefinition_of_method def #{name}
91
96
  end
97
+ RUBY
92
98
 
93
- if singleton_class?
94
- class_eval do
95
- remove_possible_method(name)
96
- define_method(name) do
97
- if instance_variable_defined? ivar
98
- instance_variable_get ivar
99
- else
100
- singleton_class.send name
101
- end
102
- end
103
- end
99
+ methods << <<~RUBY if instance_reader
100
+ silence_redefinition_of_method def #{name}
101
+ defined?(@#{name}) ? @#{name} : self.class.#{name}
104
102
  end
105
- val
106
- end
103
+ RUBY
107
104
 
108
- if instance_reader
109
- remove_possible_method name
110
- define_method(name) do
111
- if instance_variable_defined?(ivar)
112
- instance_variable_get ivar
113
- else
114
- self.class.public_send name
115
- end
105
+ class_methods << <<~RUBY
106
+ silence_redefinition_of_method def #{name}=(value)
107
+ redefine_method(:#{name}) { value } if singleton_class?
108
+ redefine_singleton_method(:#{name}) { value }
109
+ value
116
110
  end
111
+ RUBY
117
112
 
118
- remove_possible_method "#{name}?"
119
- define_method("#{name}?") { !!public_send(name) } if instance_predicate
120
- end
113
+ methods << <<~RUBY if instance_writer
114
+ silence_redefinition_of_method(:#{name}=)
115
+ attr_writer :#{name}
116
+ RUBY
121
117
 
122
- if instance_writer
123
- remove_possible_method "#{name}="
124
- attr_writer name
118
+ if instance_predicate
119
+ class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
120
+ if instance_reader
121
+ methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
122
+ end
125
123
  end
126
124
  end
125
+
126
+ location = caller_locations(1, 1).first
127
+ class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno)
128
+
129
+ attrs.each { |name| public_send("#{name}=", default) }
127
130
  end
128
131
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d,
2
4
  # but we keep this around for libraries that directly require it knowing they
3
5
  # want cattr_*. No need to deprecate.
@@ -1,11 +1,9 @@
1
- require "active_support/core_ext/module/anonymous"
2
- require "active_support/core_ext/module/reachable"
1
+ # frozen_string_literal: true
3
2
 
4
- class Class
5
- begin
6
- # Test if this Ruby supports each_object against singleton_class
7
- ObjectSpace.each_object(Numeric.singleton_class) {}
3
+ require "active_support/ruby_features"
8
4
 
5
+ class Class
6
+ if ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
9
7
  # Returns an array with all classes that are < than its receiver.
10
8
  #
11
9
  # class C; end
@@ -20,21 +18,13 @@ class Class
20
18
  # class D < C; end
21
19
  # C.descendants # => [B, A, D]
22
20
  def descendants
23
- descendants = []
24
- ObjectSpace.each_object(singleton_class) do |k|
25
- next if k.singleton_class?
26
- descendants.unshift k unless k == self
27
- end
28
- descendants
21
+ subclasses.concat(subclasses.flat_map(&:descendants))
29
22
  end
30
- rescue StandardError # JRuby 9.0.4.0 and earlier
23
+ else
31
24
  def descendants
32
- descendants = []
33
- ObjectSpace.each_object(Class) do |k|
34
- descendants.unshift k if k < self
25
+ ObjectSpace.each_object(singleton_class).reject do |k|
26
+ k.singleton_class? || k == self
35
27
  end
36
- descendants.uniq!
37
- descendants
38
28
  end
39
29
  end
40
30
 
@@ -46,10 +36,6 @@ class Class
46
36
  #
47
37
  # Foo.subclasses # => [Bar]
48
38
  def subclasses
49
- subclasses, chain = [], descendants
50
- chain.each do |k|
51
- subclasses << k unless chain.any? { |c| c > k }
52
- end
53
- subclasses
54
- end
39
+ descendants.select { |descendant| descendant.superclass == self }
40
+ end unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
55
41
  end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/class/attribute"
2
4
  require "active_support/core_ext/class/subclasses"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Date
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "date"
2
4
 
3
- class Date #:nodoc:
5
+ class Date # :nodoc:
4
6
  # No Date is blank:
5
7
  #
6
8
  # Date.today.blank? # => false
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "date"
2
4
  require "active_support/duration"
3
5
  require "active_support/core_ext/object/acts_like"
@@ -11,22 +13,22 @@ class Date
11
13
  class << self
12
14
  attr_accessor :beginning_of_week_default
13
15
 
14
- # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
16
+ # Returns the week start (e.g. +:monday+) for the current request, if this has been set (via Date.beginning_of_week=).
15
17
  # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
16
- # If no config.beginning_of_week was specified, returns :monday.
18
+ # If no +config.beginning_of_week+ was specified, returns +:monday+.
17
19
  def beginning_of_week
18
- Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
20
+ ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] || beginning_of_week_default || :monday
19
21
  end
20
22
 
21
- # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
23
+ # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. +:monday+) for current request/thread.
22
24
  #
23
25
  # This method accepts any of the following day symbols:
24
- # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
26
+ # +:monday+, +:tuesday+, +:wednesday+, +:thursday+, +:friday+, +:saturday+, +:sunday+
25
27
  def beginning_of_week=(week_start)
26
- Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
28
+ ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] = find_beginning_of_week!(week_start)
27
29
  end
28
30
 
29
- # Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
31
+ # Returns week start day symbol (e.g. +:monday+), or raises an +ArgumentError+ for invalid day symbol.
30
32
  def find_beginning_of_week!(week_start)
31
33
  raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
32
34
  week_start
@@ -85,7 +87,7 @@ class Date
85
87
  end
86
88
  alias :at_end_of_day :end_of_day
87
89
 
88
- def plus_with_duration(other) #:nodoc:
90
+ def plus_with_duration(other) # :nodoc:
89
91
  if ActiveSupport::Duration === other
90
92
  other.since(self)
91
93
  else
@@ -95,7 +97,7 @@ class Date
95
97
  alias_method :plus_without_duration, :+
96
98
  alias_method :+, :plus_with_duration
97
99
 
98
- def minus_with_duration(other) #:nodoc:
100
+ def minus_with_duration(other) # :nodoc:
99
101
  if ActiveSupport::Duration === other
100
102
  plus_with_duration(-other)
101
103
  else
@@ -108,12 +110,13 @@ class Date
108
110
  # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
109
111
  # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
110
112
  def advance(options)
111
- options = options.dup
112
113
  d = self
113
- d = d >> options.delete(:years) * 12 if options[:years]
114
- d = d >> options.delete(:months) if options[:months]
115
- d = d + options.delete(:weeks) * 7 if options[:weeks]
116
- d = d + options.delete(:days) if options[:days]
114
+
115
+ d = d >> options[:years] * 12 if options[:years]
116
+ d = d >> options[:months] if options[:months]
117
+ d = d + options[:weeks] * 7 if options[:weeks]
118
+ d = d + options[:days] if options[:days]
119
+
117
120
  d
118
121
  end
119
122
 
@@ -1,13 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "date"
2
4
  require "active_support/inflector/methods"
3
5
  require "active_support/core_ext/date/zones"
4
- require "active_support/core_ext/module/remove_method"
6
+ require "active_support/core_ext/module/redefine_method"
5
7
 
6
8
  class Date
7
9
  DATE_FORMATS = {
8
10
  short: "%d %b",
9
11
  long: "%B %d, %Y",
10
12
  db: "%Y-%m-%d",
13
+ inspect: "%Y-%m-%d",
11
14
  number: "%Y%m%d",
12
15
  long_ordinal: lambda { |date|
13
16
  day_format = ActiveSupport::Inflector.ordinalize(date.day)
@@ -17,31 +20,23 @@ class Date
17
20
  iso8601: lambda { |date| date.iso8601 }
18
21
  }
19
22
 
20
- # Ruby 1.9 has Date#to_time which converts to localtime only.
21
- remove_method :to_time
22
-
23
- # Ruby 1.9 has Date#xmlschema which converts to a string without the time
24
- # component. This removal may generate an issue on FreeBSD, that's why we
25
- # need to use remove_possible_method here
26
- remove_possible_method :xmlschema
27
-
28
23
  # Convert to a formatted string. See DATE_FORMATS for predefined formats.
29
24
  #
30
- # This method is aliased to <tt>to_s</tt>.
25
+ # This method is aliased to <tt>to_formatted_s</tt>.
31
26
  #
32
27
  # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
33
28
  #
29
+ # date.to_fs(:db) # => "2007-11-10"
34
30
  # date.to_formatted_s(:db) # => "2007-11-10"
35
- # date.to_s(:db) # => "2007-11-10"
36
31
  #
37
- # date.to_formatted_s(:short) # => "10 Nov"
38
- # date.to_formatted_s(:number) # => "20071110"
39
- # date.to_formatted_s(:long) # => "November 10, 2007"
40
- # date.to_formatted_s(:long_ordinal) # => "November 10th, 2007"
41
- # date.to_formatted_s(:rfc822) # => "10 Nov 2007"
42
- # date.to_formatted_s(:iso8601) # => "2007-11-10"
32
+ # date.to_fs(:short) # => "10 Nov"
33
+ # date.to_fs(:number) # => "20071110"
34
+ # date.to_fs(:long) # => "November 10, 2007"
35
+ # date.to_fs(:long_ordinal) # => "November 10th, 2007"
36
+ # date.to_fs(:rfc822) # => "10 Nov 2007"
37
+ # date.to_fs(:iso8601) # => "2007-11-10"
43
38
  #
44
- # == Adding your own date formats to to_formatted_s
39
+ # == Adding your own date formats to to_fs
45
40
  # You can add your own formats to the Date::DATE_FORMATS hash.
46
41
  # Use the format name as the hash key and either a strftime string
47
42
  # or Proc instance that takes a date argument as the value.
@@ -49,7 +44,7 @@ class Date
49
44
  # # config/initializers/date_formats.rb
50
45
  # Date::DATE_FORMATS[:month_and_year] = '%B %Y'
51
46
  # Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
52
- def to_formatted_s(format = :default)
47
+ def to_fs(format = :default)
53
48
  if formatter = DATE_FORMATS[format]
54
49
  if formatter.respond_to?(:call)
55
50
  formatter.call(self).to_s
@@ -60,8 +55,8 @@ class Date
60
55
  to_default_s
61
56
  end
62
57
  end
58
+ alias_method :to_formatted_s, :to_fs
63
59
  alias_method :to_default_s, :to_s
64
- alias_method :to_s, :to_formatted_s
65
60
 
66
61
  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
67
62
  def readable_inspect
@@ -70,8 +65,10 @@ class Date
70
65
  alias_method :default_inspect, :inspect
71
66
  alias_method :inspect, :readable_inspect
72
67
 
68
+ silence_redefinition_of_method :to_time
69
+
73
70
  # Converts a Date instance to a Time, where the time is set to the beginning of the day.
74
- # The timezone can be either :local or :utc (default :local).
71
+ # The timezone can be either +:local+ or +:utc+ (default +:local+).
75
72
  #
76
73
  # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
77
74
  #
@@ -79,11 +76,16 @@ class Date
79
76
  # date.to_time(:local) # => 2007-11-10 00:00:00 0800
80
77
  #
81
78
  # date.to_time(:utc) # => 2007-11-10 00:00:00 UTC
79
+ #
80
+ # NOTE: The +:local+ timezone is Ruby's *process* timezone, i.e. <tt>ENV['TZ']</tt>.
81
+ # If the <b>application's</b> timezone is needed, then use +in_time_zone+ instead.
82
82
  def to_time(form = :local)
83
83
  raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form)
84
- ::Time.send(form, year, month, day)
84
+ ::Time.public_send(form, year, month, day)
85
85
  end
86
86
 
87
+ silence_redefinition_of_method :xmlschema
88
+
87
89
  # Returns a string which represents the time in used time zone as DateTime
88
90
  # defined by XML Schema:
89
91
  #
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class Date
6
+ NOT_SET = Object.new # :nodoc:
7
+ def to_s(format = NOT_SET) # :nodoc:
8
+ if formatter = DATE_FORMATS[format]
9
+ ActiveSupport::Deprecation.warn(
10
+ "Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_fs(#{format.inspect}) instead."
11
+ )
12
+ if formatter.respond_to?(:call)
13
+ formatter.call(self).to_s
14
+ else
15
+ strftime(formatter)
16
+ end
17
+ elsif format == NOT_SET
18
+ to_default_s
19
+ else
20
+ ActiveSupport::Deprecation.warn(
21
+ "Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_fs(#{format.inspect}) instead."
22
+ )
23
+ to_default_s
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "date"
2
4
  require "active_support/core_ext/date_and_time/zones"
3
5
 
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date/acts_like"
2
4
  require "active_support/core_ext/date/blank"
3
5
  require "active_support/core_ext/date/calculations"
4
6
  require "active_support/core_ext/date/conversions"
7
+ require "active_support/core_ext/date/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
5
8
  require "active_support/core_ext/date/zones"
@@ -1,15 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/try"
4
+ require "active_support/core_ext/date_time/conversions"
2
5
 
3
6
  module DateAndTime
4
7
  module Calculations
5
8
  DAYS_INTO_WEEK = {
6
- monday: 0,
7
- tuesday: 1,
8
- wednesday: 2,
9
- thursday: 3,
10
- friday: 4,
11
- saturday: 5,
12
- sunday: 6
9
+ sunday: 0,
10
+ monday: 1,
11
+ tuesday: 2,
12
+ wednesday: 3,
13
+ thursday: 4,
14
+ friday: 5,
15
+ saturday: 6
13
16
  }
14
17
  WEEKEND_DAYS = [ 6, 0 ]
15
18
 
@@ -18,26 +21,28 @@ module DateAndTime
18
21
  advance(days: -1)
19
22
  end
20
23
 
21
- # Returns a new date/time representing the previous day.
22
- def prev_day
23
- advance(days: -1)
24
- end
25
-
26
24
  # Returns a new date/time representing tomorrow.
27
25
  def tomorrow
28
26
  advance(days: 1)
29
27
  end
30
28
 
31
- # Returns a new date/time representing the next day.
32
- def next_day
33
- advance(days: 1)
34
- end
35
-
36
29
  # Returns true if the date/time is today.
37
30
  def today?
38
31
  to_date == ::Date.current
39
32
  end
40
33
 
34
+ # Returns true if the date/time is tomorrow.
35
+ def tomorrow?
36
+ to_date == ::Date.current.tomorrow
37
+ end
38
+ alias :next_day? :tomorrow?
39
+
40
+ # Returns true if the date/time is yesterday.
41
+ def yesterday?
42
+ to_date == ::Date.current.yesterday
43
+ end
44
+ alias :prev_day? :yesterday?
45
+
41
46
  # Returns true if the date/time is in the past.
42
47
  def past?
43
48
  self < self.class.current
@@ -58,6 +63,16 @@ module DateAndTime
58
63
  !WEEKEND_DAYS.include?(wday)
59
64
  end
60
65
 
66
+ # Returns true if the date/time falls before <tt>date_or_time</tt>.
67
+ def before?(date_or_time)
68
+ self < date_or_time
69
+ end
70
+
71
+ # Returns true if the date/time falls after <tt>date_or_time</tt>.
72
+ def after?(date_or_time)
73
+ self > date_or_time
74
+ end
75
+
61
76
  # Returns a new date/time the specified number of days ago.
62
77
  def days_ago(days)
63
78
  advance(days: -days)
@@ -122,7 +137,7 @@ module DateAndTime
122
137
  # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
123
138
  # now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
124
139
  def beginning_of_quarter
125
- first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
140
+ first_quarter_month = month - (2 + month) % 3
126
141
  beginning_of_month.change(month: first_quarter_month)
127
142
  end
128
143
  alias :at_beginning_of_quarter :beginning_of_quarter
@@ -137,7 +152,7 @@ module DateAndTime
137
152
  # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
138
153
  # now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
139
154
  def end_of_quarter
140
- last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
155
+ last_quarter_month = month + (12 - month) % 3
141
156
  beginning_of_month.change(month: last_quarter_month).end_of_month
142
157
  end
143
158
  alias :at_end_of_quarter :end_of_quarter
@@ -186,21 +201,11 @@ module DateAndTime
186
201
  end
187
202
  end
188
203
 
189
- # Short-hand for months_since(1).
190
- def next_month
191
- months_since(1)
192
- end
193
-
194
- # Short-hand for months_since(3)
204
+ # Short-hand for <tt>months_since(3)</tt>.
195
205
  def next_quarter
196
206
  months_since(3)
197
207
  end
198
208
 
199
- # Short-hand for years_since(1).
200
- def next_year
201
- years_since(1)
202
- end
203
-
204
209
  # Returns a new date/time representing the given day in the previous week.
205
210
  # Week is assumed to start on +start_day+, default is
206
211
  # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
@@ -221,31 +226,28 @@ module DateAndTime
221
226
  end
222
227
  alias_method :last_weekday, :prev_weekday
223
228
 
224
- # Short-hand for months_ago(1).
225
- def prev_month
229
+ # Short-hand for <tt>months_ago(1)</tt>.
230
+ def last_month
226
231
  months_ago(1)
227
232
  end
228
- alias_method :last_month, :prev_month
229
233
 
230
- # Short-hand for months_ago(3).
234
+ # Short-hand for <tt>months_ago(3)</tt>.
231
235
  def prev_quarter
232
236
  months_ago(3)
233
237
  end
234
238
  alias_method :last_quarter, :prev_quarter
235
239
 
236
- # Short-hand for years_ago(1).
237
- def prev_year
240
+ # Short-hand for <tt>years_ago(1)</tt>.
241
+ def last_year
238
242
  years_ago(1)
239
243
  end
240
- alias_method :last_year, :prev_year
241
244
 
242
245
  # Returns the number of days to the start of the week on the given day.
243
246
  # Week is assumed to start on +start_day+, default is
244
247
  # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
245
248
  def days_to_week_start(start_day = Date.beginning_of_week)
246
- start_day_number = DAYS_INTO_WEEK[start_day]
247
- current_day_number = wday != 0 ? wday - 1 : 6
248
- (current_day_number - start_day_number) % 7
249
+ start_day_number = DAYS_INTO_WEEK.fetch(start_day)
250
+ (wday - start_day_number) % 7
249
251
  end
250
252
 
251
253
  # Returns a new date/time representing the start of this week on the given day.
@@ -320,6 +322,28 @@ module DateAndTime
320
322
  beginning_of_year..end_of_year
321
323
  end
322
324
 
325
+ # Returns a new date/time representing the next occurrence of the specified day of week.
326
+ #
327
+ # today = Date.today # => Thu, 14 Dec 2017
328
+ # today.next_occurring(:monday) # => Mon, 18 Dec 2017
329
+ # today.next_occurring(:thursday) # => Thu, 21 Dec 2017
330
+ def next_occurring(day_of_week)
331
+ from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday
332
+ from_now += 7 unless from_now > 0
333
+ advance(days: from_now)
334
+ end
335
+
336
+ # Returns a new date/time representing the previous occurrence of the specified day of week.
337
+ #
338
+ # today = Date.today # => Thu, 14 Dec 2017
339
+ # today.prev_occurring(:monday) # => Mon, 11 Dec 2017
340
+ # today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
341
+ def prev_occurring(day_of_week)
342
+ ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
343
+ ago += 7 unless ago > 0
344
+ advance(days: -ago)
345
+ end
346
+
323
347
  private
324
348
  def first_hour(date_or_time)
325
349
  date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
@@ -330,7 +354,7 @@ module DateAndTime
330
354
  end
331
355
 
332
356
  def days_span(day)
333
- (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
357
+ (DAYS_INTO_WEEK.fetch(day) - DAYS_INTO_WEEK.fetch(Date.beginning_of_week)) % 7
334
358
  end
335
359
 
336
360
  def copy_time_to(other)