activesupport 1.2.4 → 8.1.2

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 (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/time_with_zone"
4
+ require "active_support/core_ext/time/acts_like"
5
+ require "active_support/core_ext/date_and_time/zones"
6
+
7
+ class Time
8
+ include DateAndTime::Zones
9
+ class << self
10
+ attr_accessor :zone_default
11
+
12
+ # Returns the TimeZone for the current request, if this has been set (via Time.zone=).
13
+ # If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
14
+ def zone
15
+ ::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default
16
+ end
17
+
18
+ # Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
19
+ #
20
+ # This method accepts any of the following:
21
+ #
22
+ # * A \Rails TimeZone object.
23
+ # * An identifier for a \Rails TimeZone object (e.g., "Eastern \Time (US & Canada)", <tt>-5.hours</tt>).
24
+ # * A +TZInfo::Timezone+ object.
25
+ # * An identifier for a +TZInfo::Timezone+ object (e.g., "America/New_York").
26
+ #
27
+ # Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
28
+ # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
29
+ #
30
+ # class ApplicationController < ActionController::Base
31
+ # around_action :set_time_zone
32
+ #
33
+ # def set_time_zone
34
+ # if logged_in?
35
+ # Time.use_zone(current_user.time_zone) { yield }
36
+ # else
37
+ # yield
38
+ # end
39
+ # end
40
+ # end
41
+ def zone=(time_zone)
42
+ ::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone)
43
+ end
44
+
45
+ # Allows override of <tt>Time.zone</tt> locally inside supplied block;
46
+ # resets <tt>Time.zone</tt> to existing value when done.
47
+ #
48
+ # class ApplicationController < ActionController::Base
49
+ # around_action :set_time_zone
50
+ #
51
+ # private
52
+ # def set_time_zone
53
+ # Time.use_zone(current_user.timezone) { yield }
54
+ # end
55
+ # end
56
+ #
57
+ # NOTE: This won't affect any ActiveSupport::TimeWithZone
58
+ # objects that have already been created, e.g. any model timestamp
59
+ # attributes that have been read before the block will remain in
60
+ # the application's default timezone.
61
+ def use_zone(time_zone)
62
+ new_zone = find_zone!(time_zone)
63
+ begin
64
+ old_zone, ::Time.zone = ::Time.zone, new_zone
65
+ yield
66
+ ensure
67
+ ::Time.zone = old_zone
68
+ end
69
+ end
70
+
71
+ # Returns a TimeZone instance matching the time zone provided.
72
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
73
+ # Raises an +ArgumentError+ for invalid time zones.
74
+ #
75
+ # Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
76
+ # Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
77
+ # Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
78
+ # Time.find_zone! nil # => nil
79
+ # Time.find_zone! false # => false
80
+ # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
81
+ def find_zone!(time_zone)
82
+ return time_zone unless time_zone
83
+
84
+ ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}")
85
+ end
86
+
87
+ # Returns a TimeZone instance matching the time zone provided.
88
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
89
+ # Returns +nil+ for invalid time zones.
90
+ #
91
+ # Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
92
+ # Time.find_zone "NOT-A-TIMEZONE" # => nil
93
+ def find_zone(time_zone)
94
+ find_zone!(time_zone) rescue nil
95
+ end
96
+ end
97
+ end
@@ -1,7 +1,7 @@
1
- require File.dirname(__FILE__) + '/time/calculations'
2
- require File.dirname(__FILE__) + '/time/conversions'
1
+ # frozen_string_literal: true
3
2
 
4
- class Time#:nodoc:
5
- include ActiveSupport::CoreExtensions::Time::Calculations
6
- include ActiveSupport::CoreExtensions::Time::Conversions
7
- end
3
+ require_relative "time/acts_like"
4
+ require_relative "time/calculations"
5
+ require_relative "time/compatibility"
6
+ require_relative "time/conversions"
7
+ require_relative "time/zones"
@@ -1 +1,5 @@
1
- Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
1
+ # frozen_string_literal: true
2
+
3
+ (Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).sort - [File.expand_path("core_ext/benchmark.rb", __dir__)]).each do |path|
4
+ require path
5
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
4
+ def before_setup
5
+ ActiveSupport::CurrentAttributes.clear_all
6
+ super
7
+ end
8
+
9
+ def after_teardown
10
+ super
11
+ ActiveSupport::CurrentAttributes.clear_all
12
+ end
13
+ end
@@ -0,0 +1,243 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
4
+ require "active_support/execution_context"
5
+ require "active_support/core_ext/object/with"
6
+ require "active_support/core_ext/enumerable"
7
+ require "active_support/core_ext/module/delegation"
8
+
9
+ module ActiveSupport
10
+ # = Current Attributes
11
+ #
12
+ # Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
13
+ # before and after each request. This allows you to keep all the per-request attributes easily
14
+ # available to the whole system.
15
+ #
16
+ # The following full app-like example demonstrates how to use a Current class to
17
+ # facilitate easy access to the global, per-request attributes without passing them deeply
18
+ # around everywhere:
19
+ #
20
+ # # app/models/current.rb
21
+ # class Current < ActiveSupport::CurrentAttributes
22
+ # attribute :account, :user
23
+ # attribute :request_id, :user_agent, :ip_address
24
+ #
25
+ # resets { Time.zone = nil }
26
+ #
27
+ # def user=(user)
28
+ # super
29
+ # self.account = user.account
30
+ # Time.zone = user.time_zone
31
+ # end
32
+ # end
33
+ #
34
+ # # app/controllers/concerns/authentication.rb
35
+ # module Authentication
36
+ # extend ActiveSupport::Concern
37
+ #
38
+ # included do
39
+ # before_action :authenticate
40
+ # end
41
+ #
42
+ # private
43
+ # def authenticate
44
+ # if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
45
+ # Current.user = authenticated_user
46
+ # else
47
+ # redirect_to new_session_url
48
+ # end
49
+ # end
50
+ # end
51
+ #
52
+ # # app/controllers/concerns/set_current_request_details.rb
53
+ # module SetCurrentRequestDetails
54
+ # extend ActiveSupport::Concern
55
+ #
56
+ # included do
57
+ # before_action do
58
+ # Current.request_id = request.uuid
59
+ # Current.user_agent = request.user_agent
60
+ # Current.ip_address = request.ip
61
+ # end
62
+ # end
63
+ # end
64
+ #
65
+ # class ApplicationController < ActionController::Base
66
+ # include Authentication
67
+ # include SetCurrentRequestDetails
68
+ # end
69
+ #
70
+ # class MessagesController < ApplicationController
71
+ # def create
72
+ # Current.account.messages.create(message_params)
73
+ # end
74
+ # end
75
+ #
76
+ # class Message < ApplicationRecord
77
+ # belongs_to :creator, default: -> { Current.user }
78
+ # after_create { |message| Event.create(record: message) }
79
+ # end
80
+ #
81
+ # class Event < ApplicationRecord
82
+ # before_create do
83
+ # self.request_id = Current.request_id
84
+ # self.user_agent = Current.user_agent
85
+ # self.ip_address = Current.ip_address
86
+ # end
87
+ # end
88
+ #
89
+ # A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
90
+ # Current should only be used for a few, top-level globals, like account, user, and request details.
91
+ # The attributes stuck in Current should be used by more or less all actions on all requests. If you start
92
+ # sticking controller-specific attributes in there, you're going to create a mess.
93
+ class CurrentAttributes
94
+ include ActiveSupport::Callbacks
95
+ define_callbacks :reset
96
+
97
+ INVALID_ATTRIBUTE_NAMES = [:set, :reset, :resets, :instance, :before_reset, :after_reset, :reset_all, :clear_all] # :nodoc:
98
+
99
+ NOT_SET = Object.new.freeze # :nodoc:
100
+
101
+ class << self
102
+ # Returns singleton instance for this class in this thread. If none exists, one is created.
103
+ def instance
104
+ current_instances[current_instances_key] ||= new
105
+ end
106
+
107
+ # Declares one or more attributes that will be given both class and instance accessor methods.
108
+ #
109
+ # ==== Options
110
+ #
111
+ # * <tt>:default</tt> - The default value for the attributes. If the value
112
+ # is a proc or lambda, it will be called whenever an instance is
113
+ # constructed. Otherwise, the value will be duplicated with +#dup+.
114
+ # Default values are re-assigned when the attributes are reset.
115
+ def attribute(*names, default: NOT_SET)
116
+ invalid_attribute_names = names.map(&:to_sym) & INVALID_ATTRIBUTE_NAMES
117
+ if invalid_attribute_names.any?
118
+ raise ArgumentError, "Restricted attribute names: #{invalid_attribute_names.join(", ")}"
119
+ end
120
+
121
+ Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "")
122
+ Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value")
123
+
124
+ ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
125
+ names.each do |name|
126
+ owner.define_cached_method(name, namespace: :current_attributes) do |batch|
127
+ batch <<
128
+ "def #{name}" <<
129
+ "@attributes[:#{name}]" <<
130
+ "end"
131
+ end
132
+ owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
133
+ batch <<
134
+ "def #{name}=(value)" <<
135
+ "@attributes[:#{name}] = value" <<
136
+ "end"
137
+ end
138
+ end
139
+ end
140
+
141
+ self.defaults = defaults.merge(names.index_with { default })
142
+ end
143
+
144
+ # Calls this callback before #reset is called on the instance. Used for resetting external collaborators that depend on current values.
145
+ def before_reset(*methods, &block)
146
+ set_callback :reset, :before, *methods, &block
147
+ end
148
+
149
+ # Calls this callback after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
150
+ def resets(*methods, &block)
151
+ set_callback :reset, :after, *methods, &block
152
+ end
153
+ alias_method :after_reset, :resets
154
+
155
+ delegate :set, :reset, to: :instance
156
+
157
+ def clear_all # :nodoc:
158
+ if instances = current_instances
159
+ instances.values.each(&:reset)
160
+ instances.clear
161
+ end
162
+ end
163
+
164
+ private
165
+ def generated_attribute_methods
166
+ @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
167
+ end
168
+
169
+ def current_instances
170
+ ExecutionContext.current_attributes_instances
171
+ end
172
+
173
+ def current_instances_key
174
+ @current_instances_key ||= name.to_sym
175
+ end
176
+
177
+ def method_missing(name, ...)
178
+ instance.public_send(name, ...)
179
+ end
180
+
181
+ def respond_to_missing?(name, _)
182
+ instance.respond_to?(name) || super
183
+ end
184
+
185
+ def method_added(name)
186
+ super
187
+
188
+ # We try to generate instance delegators early to not rely on method_missing.
189
+ return if name == :initialize
190
+
191
+ # If the added method isn't public, we don't delegate it.
192
+ return unless public_method_defined?(name)
193
+
194
+ # If we already have a class method by that name, we don't override it.
195
+ return if singleton_class.method_defined?(name) || singleton_class.private_method_defined?(name)
196
+
197
+ Delegation.generate(singleton_class, [name], to: :instance, as: self, nilable: false)
198
+ end
199
+ end
200
+
201
+ class_attribute :defaults, instance_writer: false, default: {}.freeze
202
+
203
+ attr_writer :attributes
204
+
205
+ def initialize
206
+ @attributes = resolve_defaults
207
+ end
208
+
209
+ def attributes
210
+ @attributes.dup
211
+ end
212
+
213
+ # Expose one or more attributes within a block. Old values are returned after the block concludes.
214
+ # Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
215
+ #
216
+ # class Chat::PublicationJob < ApplicationJob
217
+ # def perform(attributes, room_number, creator)
218
+ # Current.set(person: creator) do
219
+ # Chat::Publisher.publish(attributes: attributes, room_number: room_number)
220
+ # end
221
+ # end
222
+ # end
223
+ def set(attributes, &block)
224
+ with(**attributes, &block)
225
+ end
226
+
227
+ # Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
228
+ def reset
229
+ run_callbacks :reset do
230
+ self.attributes = resolve_defaults
231
+ end
232
+ end
233
+
234
+ private
235
+ def resolve_defaults
236
+ defaults.each_with_object({}) do |(key, value), result|
237
+ if value != NOT_SET
238
+ result[key] = Proc === value ? value.call : value.dup
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Provides +deep_merge+ and +deep_merge!+ methods. Expects the including class
5
+ # to provide a <tt>merge!(other, &block)</tt> method.
6
+ module DeepMergeable # :nodoc:
7
+ # Returns a new instance with the values from +other+ merged recursively.
8
+ #
9
+ # class Hash
10
+ # include ActiveSupport::DeepMergeable
11
+ # end
12
+ #
13
+ # hash_1 = { a: true, b: { c: [1, 2, 3] } }
14
+ # hash_2 = { a: false, b: { x: [3, 4, 5] } }
15
+ #
16
+ # hash_1.deep_merge(hash_2)
17
+ # # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
18
+ #
19
+ # A block can be provided to merge non-<tt>DeepMergeable</tt> values:
20
+ #
21
+ # hash_1 = { a: 100, b: 200, c: { c1: 100 } }
22
+ # hash_2 = { b: 250, c: { c1: 200 } }
23
+ #
24
+ # hash_1.deep_merge(hash_2) do |key, this_val, other_val|
25
+ # this_val + other_val
26
+ # end
27
+ # # => { a: 100, b: 450, c: { c1: 300 } }
28
+ #
29
+ def deep_merge(other, &block)
30
+ dup.deep_merge!(other, &block)
31
+ end
32
+
33
+ # Same as #deep_merge, but modifies +self+.
34
+ def deep_merge!(other, &block)
35
+ merge!(other) do |key, this_val, other_val|
36
+ if this_val.is_a?(DeepMergeable) && this_val.deep_merge?(other_val)
37
+ this_val.deep_merge(other_val, &block)
38
+ elsif block_given?
39
+ block.call(key, this_val, other_val)
40
+ else
41
+ other_val
42
+ end
43
+ end
44
+ end
45
+
46
+ # Returns true if +other+ can be deep merged into +self+. Classes may
47
+ # override this method to restrict or expand the domain of deep mergeable
48
+ # values. Defaults to checking that +other+ is of type +self.class+.
49
+ def deep_merge?(other)
50
+ other.is_a?(self.class)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
5
+ # option is not used.
6
+ class DelegationError < NoMethodError
7
+ class << self
8
+ def nil_target(method_name, target) # :nodoc:
9
+ new("#{method_name} delegated to #{target}, but #{target} is nil")
10
+ end
11
+ end
12
+ end
13
+
14
+ module Delegation # :nodoc:
15
+ RUBY_RESERVED_KEYWORDS = %w(__ENCODING__ __LINE__ __FILE__ alias and BEGIN begin break
16
+ case class def defined? do else elsif END end ensure false for if in module next nil
17
+ not or redo rescue retry return self super then true undef unless until when while yield)
18
+ RESERVED_METHOD_NAMES = (RUBY_RESERVED_KEYWORDS + %w(_ arg args block)).to_set.freeze
19
+
20
+ class << self
21
+ def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil, nilable: true, private: nil, as: nil, signature: nil)
22
+ unless to
23
+ raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
24
+ end
25
+
26
+ if prefix == true && /^[^a-z_]/.match?(to)
27
+ raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
28
+ end
29
+
30
+ method_prefix = \
31
+ if prefix
32
+ "#{prefix == true ? to : prefix}_"
33
+ else
34
+ ""
35
+ end
36
+
37
+ location ||= caller_locations(1, 1).first
38
+ file, line = location.path, location.lineno
39
+
40
+ receiver = if to.is_a?(Module)
41
+ if to.name.nil?
42
+ raise ArgumentError, "Can't delegate to anonymous class or module: #{to}"
43
+ end
44
+
45
+ unless Inflector.safe_constantize(to.name).equal?(to)
46
+ raise ArgumentError, "Can't delegate to detached class or module: #{to.name}"
47
+ end
48
+
49
+ "::#{to.name}"
50
+ else
51
+ to.to_s
52
+ end
53
+ receiver = "self.#{receiver}" if RESERVED_METHOD_NAMES.include?(receiver)
54
+
55
+ explicit_receiver = false
56
+ receiver_class = if as
57
+ explicit_receiver = true
58
+ as
59
+ elsif to.is_a?(Module)
60
+ to.singleton_class
61
+ elsif receiver == "self.class"
62
+ nilable = false # self.class can't possibly be nil
63
+ owner.singleton_class
64
+ end
65
+
66
+ method_def = []
67
+ method_names = []
68
+
69
+ method_def << "self.private" if private
70
+
71
+ methods.each do |method|
72
+ method_name = prefix ? "#{method_prefix}#{method}" : method
73
+ method_names << method_name.to_sym
74
+
75
+ # Attribute writer methods only accept one argument. Makes sure []=
76
+ # methods still accept two arguments.
77
+ definition = \
78
+ if signature
79
+ signature
80
+ elsif /[^\]]=\z/.match?(method)
81
+ "arg"
82
+ else
83
+ method_object = if receiver_class
84
+ begin
85
+ receiver_class.public_instance_method(method)
86
+ rescue NameError
87
+ raise if explicit_receiver
88
+ # Do nothing. Fall back to `"..."`
89
+ end
90
+ end
91
+
92
+ if method_object
93
+ parameters = method_object.parameters
94
+
95
+ if parameters.map(&:first).intersect?([:opt, :rest, :keyreq, :key, :keyrest])
96
+ "..."
97
+ else
98
+ defn = parameters.filter_map { |type, arg| arg if type == :req }
99
+ defn << "&"
100
+ defn.join(", ")
101
+ end
102
+ else
103
+ "..."
104
+ end
105
+ end
106
+
107
+ # The following generated method calls the target exactly once, storing
108
+ # the returned value in a dummy variable.
109
+ #
110
+ # Reason is twofold: On one hand doing less calls is in general better.
111
+ # On the other hand it could be that the target has side-effects,
112
+ # whereas conceptually, from the user point of view, the delegator should
113
+ # be doing one call.
114
+ if nilable == false
115
+ method_def <<
116
+ "def #{method_name}(#{definition})" <<
117
+ " (#{receiver}).#{method}(#{definition})" <<
118
+ "end"
119
+ elsif allow_nil
120
+ method = method.to_s
121
+
122
+ method_def <<
123
+ "def #{method_name}(#{definition})" <<
124
+ " _ = #{receiver}" <<
125
+ " if !_.nil? || nil.respond_to?(:#{method})" <<
126
+ " _.#{method}(#{definition})" <<
127
+ " end" <<
128
+ "end"
129
+ else
130
+ method = method.to_s
131
+ method_name = method_name.to_s
132
+
133
+ method_def <<
134
+ "def #{method_name}(#{definition})" <<
135
+ " _ = #{receiver}" <<
136
+ " _.#{method}(#{definition})" <<
137
+ "rescue ::NoMethodError => e" <<
138
+ " if _.nil? && e.name == :#{method}" <<
139
+ " ::Kernel.raise ::ActiveSupport::DelegationError.nil_target(:#{method_name}, :'#{receiver}')" <<
140
+ " else" <<
141
+ " ::Kernel.raise" <<
142
+ " end" <<
143
+ "end"
144
+ end
145
+ end
146
+ owner.module_eval(method_def.join(";"), file, line)
147
+ method_names
148
+ end
149
+
150
+ def generate_method_missing(owner, target, allow_nil: nil)
151
+ target = target.to_s
152
+ target = "self.#{target}" if RESERVED_METHOD_NAMES.include?(target) || target == "__target"
153
+
154
+ nil_behavior = if allow_nil
155
+ "nil"
156
+ else
157
+ "::Kernel.raise ::ActiveSupport::DelegationError.nil_target(method, :'#{target}')"
158
+ end
159
+
160
+ owner.module_eval <<~RUBY, __FILE__, __LINE__ + 1
161
+ def respond_to_missing?(name, include_private = false)
162
+ # It may look like an oversight, but we deliberately do not pass
163
+ # +include_private+, because they do not get delegated.
164
+
165
+ return false if name == :marshal_dump || name == :_dump
166
+ #{target}.respond_to?(name) || super
167
+ end
168
+
169
+ def method_missing(method, ...)
170
+ __target = #{target}
171
+ if __target.nil? && !nil.respond_to?(method)
172
+ #{nil_behavior}
173
+ elsif __target.respond_to?(method)
174
+ __target.public_send(method, ...)
175
+ else
176
+ super
177
+ end
178
+ end
179
+ RUBY
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/inflector/methods"
4
+
5
+ module ActiveSupport
6
+ # = Active Support \Autoload
7
+ #
8
+ # Autoload and eager load conveniences for your library.
9
+ #
10
+ # This module allows you to define autoloads based on
11
+ # \Rails conventions (i.e. no need to define the path
12
+ # it is automatically guessed based on the filename)
13
+ # and also define a set of constants that needs to be
14
+ # eager loaded:
15
+ #
16
+ # module MyLib
17
+ # extend ActiveSupport::Autoload
18
+ #
19
+ # autoload :Model
20
+ #
21
+ # eager_autoload do
22
+ # autoload :Cache
23
+ # end
24
+ # end
25
+ #
26
+ # Then your library can be eager loaded by simply calling:
27
+ #
28
+ # MyLib.eager_load!
29
+ module Autoload
30
+ def autoload(const_name, path = @_at_path)
31
+ unless path
32
+ full = [name, @_under_path, const_name.to_s].compact.join("::")
33
+ path = Inflector.underscore(full)
34
+ end
35
+
36
+ if @_eager_autoload
37
+ @_eagerloaded_constants ||= []
38
+ @_eagerloaded_constants << const_name
39
+ end
40
+
41
+ super const_name, path
42
+ end
43
+
44
+ def autoload_under(path)
45
+ @_under_path, old_path = path, @_under_path
46
+ yield
47
+ ensure
48
+ @_under_path = old_path
49
+ end
50
+
51
+ def autoload_at(path)
52
+ @_at_path, old_path = path, @_at_path
53
+ yield
54
+ ensure
55
+ @_at_path = old_path
56
+ end
57
+
58
+ def eager_autoload
59
+ old_eager, @_eager_autoload = @_eager_autoload, true
60
+ yield
61
+ ensure
62
+ @_eager_autoload = old_eager
63
+ end
64
+
65
+ def eager_load!
66
+ if @_eagerloaded_constants
67
+ @_eagerloaded_constants.each { |const_name| const_get(const_name) }
68
+ @_eagerloaded_constants = nil
69
+ end
70
+ end
71
+ end
72
+ end