activesupport 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +572 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support.rb +96 -0
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/all.rb +5 -0
  8. data/lib/active_support/array_inquirer.rb +48 -0
  9. data/lib/active_support/backtrace_cleaner.rb +132 -0
  10. data/lib/active_support/benchmarkable.rb +51 -0
  11. data/lib/active_support/builder.rb +8 -0
  12. data/lib/active_support/cache.rb +830 -0
  13. data/lib/active_support/cache/file_store.rb +196 -0
  14. data/lib/active_support/cache/mem_cache_store.rb +212 -0
  15. data/lib/active_support/cache/memory_store.rb +174 -0
  16. data/lib/active_support/cache/null_store.rb +48 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +488 -0
  18. data/lib/active_support/cache/strategy/local_cache.rb +194 -0
  19. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  20. data/lib/active_support/callbacks.rb +856 -0
  21. data/lib/active_support/concern.rb +171 -0
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  23. data/lib/active_support/concurrency/share_lock.rb +227 -0
  24. data/lib/active_support/configurable.rb +146 -0
  25. data/lib/active_support/core_ext.rb +5 -0
  26. data/lib/active_support/core_ext/array.rb +9 -0
  27. data/lib/active_support/core_ext/array/access.rb +104 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +213 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
  34. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  35. data/lib/active_support/core_ext/benchmark.rb +16 -0
  36. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  37. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  38. data/lib/active_support/core_ext/class.rb +4 -0
  39. data/lib/active_support/core_ext/class/attribute.rb +141 -0
  40. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  41. data/lib/active_support/core_ext/class/subclasses.rb +54 -0
  42. data/lib/active_support/core_ext/date.rb +7 -0
  43. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  44. data/lib/active_support/core_ext/date/blank.rb +14 -0
  45. data/lib/active_support/core_ext/date/calculations.rb +146 -0
  46. data/lib/active_support/core_ext/date/conversions.rb +96 -0
  47. data/lib/active_support/core_ext/date/zones.rb +8 -0
  48. data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
  49. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  50. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  51. data/lib/active_support/core_ext/date_time.rb +7 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  57. data/lib/active_support/core_ext/digest.rb +3 -0
  58. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  59. data/lib/active_support/core_ext/enumerable.rb +188 -0
  60. data/lib/active_support/core_ext/file.rb +3 -0
  61. data/lib/active_support/core_ext/file/atomic.rb +70 -0
  62. data/lib/active_support/core_ext/hash.rb +10 -0
  63. data/lib/active_support/core_ext/hash/compact.rb +5 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +263 -0
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +24 -0
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
  69. data/lib/active_support/core_ext/hash/keys.rb +143 -0
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  71. data/lib/active_support/core_ext/hash/slice.rb +26 -0
  72. data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
  73. data/lib/active_support/core_ext/integer.rb +5 -0
  74. data/lib/active_support/core_ext/integer/inflections.rb +31 -0
  75. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  76. data/lib/active_support/core_ext/integer/time.rb +22 -0
  77. data/lib/active_support/core_ext/kernel.rb +5 -0
  78. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  79. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  80. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  81. data/lib/active_support/core_ext/load_error.rb +9 -0
  82. data/lib/active_support/core_ext/marshal.rb +24 -0
  83. data/lib/active_support/core_ext/module.rb +13 -0
  84. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  85. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  86. data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
  87. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  88. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  89. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  90. data/lib/active_support/core_ext/module/delegation.rb +313 -0
  91. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  92. data/lib/active_support/core_ext/module/introspection.rb +86 -0
  93. data/lib/active_support/core_ext/module/reachable.rb +6 -0
  94. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  95. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  96. data/lib/active_support/core_ext/name_error.rb +38 -0
  97. data/lib/active_support/core_ext/numeric.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
  99. data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
  100. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  101. data/lib/active_support/core_ext/numeric/time.rb +66 -0
  102. data/lib/active_support/core_ext/object.rb +16 -0
  103. data/lib/active_support/core_ext/object/acts_like.rb +21 -0
  104. data/lib/active_support/core_ext/object/blank.rb +155 -0
  105. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  106. data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
  107. data/lib/active_support/core_ext/object/duplicable.rb +49 -0
  108. data/lib/active_support/core_ext/object/inclusion.rb +29 -0
  109. data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
  110. data/lib/active_support/core_ext/object/json.rb +228 -0
  111. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  112. data/lib/active_support/core_ext/object/to_query.rb +89 -0
  113. data/lib/active_support/core_ext/object/try.rb +156 -0
  114. data/lib/active_support/core_ext/object/with_options.rb +82 -0
  115. data/lib/active_support/core_ext/range.rb +7 -0
  116. data/lib/active_support/core_ext/range/compare_range.rb +70 -0
  117. data/lib/active_support/core_ext/range/conversions.rb +41 -0
  118. data/lib/active_support/core_ext/range/each.rb +25 -0
  119. data/lib/active_support/core_ext/range/include_range.rb +9 -0
  120. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  121. data/lib/active_support/core_ext/range/overlaps.rb +10 -0
  122. data/lib/active_support/core_ext/regexp.rb +7 -0
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string.rb +15 -0
  125. data/lib/active_support/core_ext/string/access.rb +114 -0
  126. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  127. data/lib/active_support/core_ext/string/conversions.rb +59 -0
  128. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  129. data/lib/active_support/core_ext/string/filters.rb +145 -0
  130. data/lib/active_support/core_ext/string/indent.rb +45 -0
  131. data/lib/active_support/core_ext/string/inflections.rb +259 -0
  132. data/lib/active_support/core_ext/string/inquiry.rb +15 -0
  133. data/lib/active_support/core_ext/string/multibyte.rb +58 -0
  134. data/lib/active_support/core_ext/string/output_safety.rb +314 -0
  135. data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
  136. data/lib/active_support/core_ext/string/strip.rb +27 -0
  137. data/lib/active_support/core_ext/string/zones.rb +16 -0
  138. data/lib/active_support/core_ext/time.rb +7 -0
  139. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  140. data/lib/active_support/core_ext/time/calculations.rb +344 -0
  141. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  142. data/lib/active_support/core_ext/time/conversions.rb +72 -0
  143. data/lib/active_support/core_ext/time/zones.rb +113 -0
  144. data/lib/active_support/core_ext/uri.rb +25 -0
  145. data/lib/active_support/current_attributes.rb +203 -0
  146. data/lib/active_support/dependencies.rb +806 -0
  147. data/lib/active_support/dependencies/autoload.rb +79 -0
  148. data/lib/active_support/dependencies/interlock.rb +57 -0
  149. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  150. data/lib/active_support/deprecation.rb +46 -0
  151. data/lib/active_support/deprecation/behaviors.rb +109 -0
  152. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  153. data/lib/active_support/deprecation/instance_delegator.rb +39 -0
  154. data/lib/active_support/deprecation/method_wrappers.rb +78 -0
  155. data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
  156. data/lib/active_support/deprecation/reporting.rb +114 -0
  157. data/lib/active_support/descendants_tracker.rb +109 -0
  158. data/lib/active_support/digest.rb +20 -0
  159. data/lib/active_support/duration.rb +433 -0
  160. data/lib/active_support/duration/iso8601_parser.rb +124 -0
  161. data/lib/active_support/duration/iso8601_serializer.rb +54 -0
  162. data/lib/active_support/encrypted_configuration.rb +45 -0
  163. data/lib/active_support/encrypted_file.rb +100 -0
  164. data/lib/active_support/evented_file_update_checker.rb +235 -0
  165. data/lib/active_support/execution_wrapper.rb +129 -0
  166. data/lib/active_support/executor.rb +8 -0
  167. data/lib/active_support/file_update_checker.rb +163 -0
  168. data/lib/active_support/gem_version.rb +17 -0
  169. data/lib/active_support/gzip.rb +38 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +399 -0
  171. data/lib/active_support/i18n.rb +16 -0
  172. data/lib/active_support/i18n_railtie.rb +126 -0
  173. data/lib/active_support/inflections.rb +72 -0
  174. data/lib/active_support/inflector.rb +9 -0
  175. data/lib/active_support/inflector/inflections.rb +257 -0
  176. data/lib/active_support/inflector/methods.rb +398 -0
  177. data/lib/active_support/inflector/transliterate.rb +147 -0
  178. data/lib/active_support/json.rb +4 -0
  179. data/lib/active_support/json/decoding.rb +76 -0
  180. data/lib/active_support/json/encoding.rb +134 -0
  181. data/lib/active_support/key_generator.rb +41 -0
  182. data/lib/active_support/lazy_load_hooks.rb +82 -0
  183. data/lib/active_support/locale/en.rb +31 -0
  184. data/lib/active_support/locale/en.yml +135 -0
  185. data/lib/active_support/log_subscriber.rb +135 -0
  186. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  187. data/lib/active_support/logger.rb +93 -0
  188. data/lib/active_support/logger_silence.rb +45 -0
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -0
  190. data/lib/active_support/message_encryptor.rb +227 -0
  191. data/lib/active_support/message_verifier.rb +205 -0
  192. data/lib/active_support/messages/metadata.rb +71 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  194. data/lib/active_support/messages/rotator.rb +56 -0
  195. data/lib/active_support/multibyte.rb +23 -0
  196. data/lib/active_support/multibyte/chars.rb +216 -0
  197. data/lib/active_support/multibyte/unicode.rb +157 -0
  198. data/lib/active_support/notifications.rb +253 -0
  199. data/lib/active_support/notifications/fanout.rb +244 -0
  200. data/lib/active_support/notifications/instrumenter.rb +164 -0
  201. data/lib/active_support/number_helper.rb +378 -0
  202. data/lib/active_support/number_helper/number_converter.rb +184 -0
  203. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  204. data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
  205. data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
  206. data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
  207. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  208. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  209. data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
  210. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  211. data/lib/active_support/option_merger.rb +27 -0
  212. data/lib/active_support/ordered_hash.rb +50 -0
  213. data/lib/active_support/ordered_options.rb +85 -0
  214. data/lib/active_support/parameter_filter.rb +129 -0
  215. data/lib/active_support/per_thread_registry.rb +60 -0
  216. data/lib/active_support/proxy_object.rb +15 -0
  217. data/lib/active_support/rails.rb +29 -0
  218. data/lib/active_support/railtie.rb +80 -0
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +174 -0
  221. data/lib/active_support/security_utils.rb +31 -0
  222. data/lib/active_support/string_inquirer.rb +34 -0
  223. data/lib/active_support/subscriber.rb +169 -0
  224. data/lib/active_support/tagged_logging.rb +88 -0
  225. data/lib/active_support/test_case.rb +163 -0
  226. data/lib/active_support/testing/assertions.rb +228 -0
  227. data/lib/active_support/testing/autorun.rb +7 -0
  228. data/lib/active_support/testing/constant_lookup.rb +51 -0
  229. data/lib/active_support/testing/declarative.rb +28 -0
  230. data/lib/active_support/testing/deprecation.rb +38 -0
  231. data/lib/active_support/testing/file_fixtures.rb +38 -0
  232. data/lib/active_support/testing/isolation.rb +110 -0
  233. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  234. data/lib/active_support/testing/parallelization.rb +128 -0
  235. data/lib/active_support/testing/setup_and_teardown.rb +55 -0
  236. data/lib/active_support/testing/stream.rb +44 -0
  237. data/lib/active_support/testing/tagged_logging.rb +27 -0
  238. data/lib/active_support/testing/time_helpers.rb +200 -0
  239. data/lib/active_support/time.rb +20 -0
  240. data/lib/active_support/time_with_zone.rb +561 -0
  241. data/lib/active_support/values/time_zone.rb +570 -0
  242. data/lib/active_support/version.rb +10 -0
  243. data/lib/active_support/xml_mini.rb +202 -0
  244. data/lib/active_support/xml_mini/jdom.rb +183 -0
  245. data/lib/active_support/xml_mini/libxml.rb +80 -0
  246. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  247. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  248. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  249. data/lib/active_support/xml_mini/rexml.rb +130 -0
  250. metadata +385 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/array_inquirer"
4
+
5
+ class Array
6
+ # Wraps the array in an +ArrayInquirer+ object, which gives a friendlier way
7
+ # to check its string-like contents.
8
+ #
9
+ # pets = [:cat, :dog].inquiry
10
+ #
11
+ # pets.cat? # => true
12
+ # pets.ferret? # => false
13
+ #
14
+ # pets.any?(:cat, :ferret) # => true
15
+ # pets.any?(:ferret, :alligator) # => false
16
+ def inquiry
17
+ ActiveSupport::ArrayInquirer.new(self)
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+
5
+ ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Array#append and Array#prepend natively, so requiring active_support/core_ext/array/prepend_and_append is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Wraps its argument in an array unless it is already an array (or array-like).
5
+ #
6
+ # Specifically:
7
+ #
8
+ # * If the argument is +nil+ an empty array is returned.
9
+ # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
10
+ # * Otherwise, returns an array with the argument as its single element.
11
+ #
12
+ # Array.wrap(nil) # => []
13
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
14
+ # Array.wrap(0) # => [0]
15
+ #
16
+ # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
17
+ #
18
+ # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
19
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
20
+ # an array with the argument as its single element right away.
21
+ # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
22
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
23
+ # * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
24
+ # it returns an array with the argument as its single element.
25
+ #
26
+ # The last point is easily explained with some enumerables:
27
+ #
28
+ # Array(foo: :bar) # => [[:foo, :bar]]
29
+ # Array.wrap(foo: :bar) # => [{:foo=>:bar}]
30
+ #
31
+ # There's also a related idiom that uses the splat operator:
32
+ #
33
+ # [*object]
34
+ #
35
+ # which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
36
+ #
37
+ # The differences with <tt>Kernel#Array</tt> explained above
38
+ # apply to the rest of <tt>object</tt>s.
39
+ def self.wrap(object)
40
+ if object.nil?
41
+ []
42
+ elsif object.respond_to?(:to_ary)
43
+ object.to_ary || [object]
44
+ else
45
+ [object]
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "benchmark"
4
+
5
+ class << Benchmark
6
+ # Benchmark realtime in milliseconds.
7
+ #
8
+ # Benchmark.realtime { User.all }
9
+ # # => 8.0e-05
10
+ #
11
+ # Benchmark.ms { User.all }
12
+ # # => 0.074
13
+ def ms
14
+ 1000 * realtime { yield }
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/big_decimal/conversions"
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bigdecimal"
4
+ require "bigdecimal/util"
5
+
6
+ module ActiveSupport
7
+ module BigDecimalWithDefaultFormat #:nodoc:
8
+ def to_s(format = "F")
9
+ super(format)
10
+ end
11
+ end
12
+ end
13
+
14
+ BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat)
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/class/attribute"
4
+ require "active_support/core_ext/class/subclasses"
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/kernel/singleton_class"
4
+ require "active_support/core_ext/module/redefine_method"
5
+ require "active_support/core_ext/array/extract_options"
6
+
7
+ class Class
8
+ # Declare a class-level attribute whose value is inheritable by subclasses.
9
+ # Subclasses can change their own value and it will not impact parent class.
10
+ #
11
+ # ==== Options
12
+ #
13
+ # * <tt>:instance_reader</tt> - Sets the instance reader method (defaults to true).
14
+ # * <tt>:instance_writer</tt> - Sets the instance writer method (defaults to true).
15
+ # * <tt>:instance_accessor</tt> - Sets both instance methods (defaults to true).
16
+ # * <tt>:instance_predicate</tt> - Sets a predicate method (defaults to true).
17
+ # * <tt>:default</tt> - Sets a default value for the attribute (defaults to nil).
18
+ #
19
+ # ==== Examples
20
+ #
21
+ # class Base
22
+ # class_attribute :setting
23
+ # end
24
+ #
25
+ # class Subclass < Base
26
+ # end
27
+ #
28
+ # Base.setting = true
29
+ # Subclass.setting # => true
30
+ # Subclass.setting = false
31
+ # Subclass.setting # => false
32
+ # Base.setting # => true
33
+ #
34
+ # In the above case as long as Subclass does not assign a value to setting
35
+ # by performing <tt>Subclass.setting = _something_</tt>, <tt>Subclass.setting</tt>
36
+ # would read value assigned to parent class. Once Subclass assigns a value then
37
+ # the value assigned by Subclass would be returned.
38
+ #
39
+ # This matches normal Ruby method inheritance: think of writing an attribute
40
+ # on a subclass as overriding the reader method. However, you need to be aware
41
+ # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
42
+ # In such cases, you don't want to do changes in place. Instead use setters:
43
+ #
44
+ # Base.setting = []
45
+ # Base.setting # => []
46
+ # Subclass.setting # => []
47
+ #
48
+ # # Appending in child changes both parent and child because it is the same object:
49
+ # Subclass.setting << :foo
50
+ # Base.setting # => [:foo]
51
+ # Subclass.setting # => [:foo]
52
+ #
53
+ # # Use setters to not propagate changes:
54
+ # Base.setting = []
55
+ # Subclass.setting += [:foo]
56
+ # Base.setting # => []
57
+ # Subclass.setting # => [:foo]
58
+ #
59
+ # For convenience, an instance predicate method is defined as well.
60
+ # To skip it, pass <tt>instance_predicate: false</tt>.
61
+ #
62
+ # Subclass.setting? # => false
63
+ #
64
+ # Instances may overwrite the class value in the same way:
65
+ #
66
+ # Base.setting = true
67
+ # object = Base.new
68
+ # object.setting # => true
69
+ # object.setting = false
70
+ # object.setting # => false
71
+ # Base.setting # => true
72
+ #
73
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
74
+ #
75
+ # object.setting # => NoMethodError
76
+ # object.setting? # => NoMethodError
77
+ #
78
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
79
+ #
80
+ # object.setting = false # => NoMethodError
81
+ #
82
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
83
+ #
84
+ # To set a default value for the attribute, pass <tt>default:</tt>, like so:
85
+ #
86
+ # class_attribute :settings, default: {}
87
+ def class_attribute(
88
+ *attrs,
89
+ instance_accessor: true,
90
+ instance_reader: instance_accessor,
91
+ instance_writer: instance_accessor,
92
+ instance_predicate: true,
93
+ default: nil
94
+ )
95
+ attrs.each do |name|
96
+ singleton_class.silence_redefinition_of_method(name)
97
+ define_singleton_method(name) { default }
98
+
99
+ singleton_class.silence_redefinition_of_method("#{name}?")
100
+ define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
101
+
102
+ ivar = "@#{name}".to_sym
103
+
104
+ singleton_class.silence_redefinition_of_method("#{name}=")
105
+ define_singleton_method("#{name}=") do |val|
106
+ redefine_singleton_method(name) { val }
107
+
108
+ if singleton_class?
109
+ class_eval do
110
+ redefine_method(name) do
111
+ if instance_variable_defined? ivar
112
+ instance_variable_get ivar
113
+ else
114
+ singleton_class.send name
115
+ end
116
+ end
117
+ end
118
+ end
119
+ val
120
+ end
121
+
122
+ if instance_reader
123
+ redefine_method(name) do
124
+ if instance_variable_defined?(ivar)
125
+ instance_variable_get ivar
126
+ else
127
+ self.class.public_send name
128
+ end
129
+ end
130
+
131
+ redefine_method("#{name}?") { !!public_send(name) } if instance_predicate
132
+ end
133
+
134
+ if instance_writer
135
+ redefine_method("#{name}=") do |val|
136
+ instance_variable_set ivar, val
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d,
4
+ # but we keep this around for libraries that directly require it knowing they
5
+ # want cattr_*. No need to deprecate.
6
+ require "active_support/core_ext/module/attribute_accessors"
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Class
4
+ begin
5
+ # Test if this Ruby supports each_object against singleton_class
6
+ ObjectSpace.each_object(Numeric.singleton_class) { }
7
+
8
+ # Returns an array with all classes that are < than its receiver.
9
+ #
10
+ # class C; end
11
+ # C.descendants # => []
12
+ #
13
+ # class B < C; end
14
+ # C.descendants # => [B]
15
+ #
16
+ # class A < B; end
17
+ # C.descendants # => [B, A]
18
+ #
19
+ # class D < C; end
20
+ # C.descendants # => [B, A, D]
21
+ def descendants
22
+ descendants = []
23
+ ObjectSpace.each_object(singleton_class) do |k|
24
+ next if k.singleton_class?
25
+ descendants.unshift k unless k == self
26
+ end
27
+ descendants
28
+ end
29
+ rescue StandardError # JRuby 9.0.4.0 and earlier
30
+ def descendants
31
+ descendants = []
32
+ ObjectSpace.each_object(Class) do |k|
33
+ descendants.unshift k if k < self
34
+ end
35
+ descendants.uniq!
36
+ descendants
37
+ end
38
+ end
39
+
40
+ # Returns an array with the direct children of +self+.
41
+ #
42
+ # class Foo; end
43
+ # class Bar < Foo; end
44
+ # class Baz < Bar; end
45
+ #
46
+ # Foo.subclasses # => [Bar]
47
+ def subclasses
48
+ subclasses, chain = [], descendants
49
+ chain.each do |k|
50
+ subclasses << k unless chain.any? { |c| c > k }
51
+ end
52
+ subclasses
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/date/acts_like"
4
+ require "active_support/core_ext/date/blank"
5
+ require "active_support/core_ext/date/calculations"
6
+ require "active_support/core_ext/date/conversions"
7
+ require "active_support/core_ext/date/zones"
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/acts_like"
4
+
5
+ class Date
6
+ # Duck-types as a Date-like class. See Object#acts_like?.
7
+ def acts_like_date?
8
+ true
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ class Date #:nodoc:
6
+ # No Date is blank:
7
+ #
8
+ # Date.today.blank? # => false
9
+ #
10
+ # @return [false]
11
+ def blank?
12
+ false
13
+ end
14
+ end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "active_support/duration"
5
+ require "active_support/core_ext/object/acts_like"
6
+ require "active_support/core_ext/date/zones"
7
+ require "active_support/core_ext/time/zones"
8
+ require "active_support/core_ext/date_and_time/calculations"
9
+
10
+ class Date
11
+ include DateAndTime::Calculations
12
+
13
+ class << self
14
+ attr_accessor :beginning_of_week_default
15
+
16
+ # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
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>.
18
+ # If no config.beginning_of_week was specified, returns :monday.
19
+ def beginning_of_week
20
+ Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
21
+ end
22
+
23
+ # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
24
+ #
25
+ # This method accepts any of the following day symbols:
26
+ # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
27
+ def beginning_of_week=(week_start)
28
+ Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
29
+ end
30
+
31
+ # Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
32
+ def find_beginning_of_week!(week_start)
33
+ raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
34
+ week_start
35
+ end
36
+
37
+ # Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
38
+ def yesterday
39
+ ::Date.current.yesterday
40
+ end
41
+
42
+ # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).
43
+ def tomorrow
44
+ ::Date.current.tomorrow
45
+ end
46
+
47
+ # Returns Time.zone.today when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns Date.today.
48
+ def current
49
+ ::Time.zone ? ::Time.zone.today : ::Date.today
50
+ end
51
+ end
52
+
53
+ # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
54
+ # and then subtracts the specified number of seconds.
55
+ def ago(seconds)
56
+ in_time_zone.since(-seconds)
57
+ end
58
+
59
+ # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
60
+ # and then adds the specified number of seconds
61
+ def since(seconds)
62
+ in_time_zone.since(seconds)
63
+ end
64
+ alias :in :since
65
+
66
+ # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
67
+ def beginning_of_day
68
+ in_time_zone
69
+ end
70
+ alias :midnight :beginning_of_day
71
+ alias :at_midnight :beginning_of_day
72
+ alias :at_beginning_of_day :beginning_of_day
73
+
74
+ # Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00)
75
+ def middle_of_day
76
+ in_time_zone.middle_of_day
77
+ end
78
+ alias :midday :middle_of_day
79
+ alias :noon :middle_of_day
80
+ alias :at_midday :middle_of_day
81
+ alias :at_noon :middle_of_day
82
+ alias :at_middle_of_day :middle_of_day
83
+
84
+ # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
85
+ def end_of_day
86
+ in_time_zone.end_of_day
87
+ end
88
+ alias :at_end_of_day :end_of_day
89
+
90
+ def plus_with_duration(other) #:nodoc:
91
+ if ActiveSupport::Duration === other
92
+ other.since(self)
93
+ else
94
+ plus_without_duration(other)
95
+ end
96
+ end
97
+ alias_method :plus_without_duration, :+
98
+ alias_method :+, :plus_with_duration
99
+
100
+ def minus_with_duration(other) #:nodoc:
101
+ if ActiveSupport::Duration === other
102
+ plus_with_duration(-other)
103
+ else
104
+ minus_without_duration(other)
105
+ end
106
+ end
107
+ alias_method :minus_without_duration, :-
108
+ alias_method :-, :minus_with_duration
109
+
110
+ # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
111
+ # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
112
+ def advance(options)
113
+ d = self
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
+
120
+ d
121
+ end
122
+
123
+ # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
124
+ # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
125
+ #
126
+ # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1)
127
+ # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
128
+ def change(options)
129
+ ::Date.new(
130
+ options.fetch(:year, year),
131
+ options.fetch(:month, month),
132
+ options.fetch(:day, day)
133
+ )
134
+ end
135
+
136
+ # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
137
+ def compare_with_coercion(other)
138
+ if other.is_a?(Time)
139
+ to_datetime <=> other
140
+ else
141
+ compare_without_coercion(other)
142
+ end
143
+ end
144
+ alias_method :compare_without_coercion, :<=>
145
+ alias_method :<=>, :compare_with_coercion
146
+ end