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
@@ -1,29 +1,212 @@
1
- module ActiveSupport #:nodoc:
2
- module CoreExtensions #:nodoc:
3
- module Array #:nodoc:
4
- # Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three"
5
- module Conversions
6
- # Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options:
7
- # * <tt>:connector</tt>: The word used to join the last element in arrays with more than two elements (default: "and")
8
- # * <tt>:skip_last_comma</tt>: Set to true to return "a, b and c" instead of "a, b, and c".
9
- def to_sentence(options = {})
10
- options.assert_valid_keys(:connector, :skip_last_comma)
11
- options.reverse_merge! :connector => 'and', :skip_last_comma => false
12
-
13
- case length
14
- when 1
15
- self[0]
16
- when 2
17
- "#{self[0]} #{options[:connector]} #{self[1]}"
18
- else
19
- "#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]} #{self[-1]}"
20
- end
21
- end
22
-
23
- # When an array is given to url_for, it is converted to a slash separated string.
24
- def to_param
25
- join '/'
26
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+ require "active_support/core_ext/string/inflections"
5
+ require "active_support/core_ext/object/to_param"
6
+ require "active_support/core_ext/object/to_query"
7
+
8
+ class Array
9
+ # Converts the array to a comma-separated sentence where the last element is
10
+ # joined by the connector word.
11
+ #
12
+ # You can pass the following options to change the default behavior. If you
13
+ # pass an option key that doesn't exist in the list below, it will raise an
14
+ # <tt>ArgumentError</tt>.
15
+ #
16
+ # ==== Options
17
+ #
18
+ # * <tt>:words_connector</tt> - The sign or word used to join all but the last
19
+ # element in arrays with three or more elements (default: <tt>", "</tt>).
20
+ # * <tt>:last_word_connector</tt> - The sign or word used to join the last element
21
+ # in arrays with three or more elements (default: <tt>", and "</tt>).
22
+ # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
23
+ # in arrays with two elements (default: <tt>" and "</tt>).
24
+ # * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
25
+ # the connector options defined on the 'support.array' namespace in the
26
+ # corresponding dictionary file.
27
+ #
28
+ # ==== Examples
29
+ #
30
+ # [].to_sentence # => ""
31
+ # ['one'].to_sentence # => "one"
32
+ # ['one', 'two'].to_sentence # => "one and two"
33
+ # ['one', 'two', 'three'].to_sentence # => "one, two, and three"
34
+ #
35
+ # ['one', 'two'].to_sentence(passing: 'invalid option')
36
+ # # => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
37
+ #
38
+ # ['one', 'two'].to_sentence(two_words_connector: '-')
39
+ # # => "one-two"
40
+ #
41
+ # ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
42
+ # # => "one or two or at least three"
43
+ #
44
+ # Using <tt>:locale</tt> option:
45
+ #
46
+ # # Given this locale dictionary:
47
+ # #
48
+ # # es:
49
+ # # support:
50
+ # # array:
51
+ # # words_connector: " o "
52
+ # # two_words_connector: " y "
53
+ # # last_word_connector: " o al menos "
54
+ #
55
+ # ['uno', 'dos'].to_sentence(locale: :es)
56
+ # # => "uno y dos"
57
+ #
58
+ # ['uno', 'dos', 'tres'].to_sentence(locale: :es)
59
+ # # => "uno o dos o al menos tres"
60
+ def to_sentence(options = {})
61
+ options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
62
+
63
+ default_connectors = {
64
+ words_connector: ", ",
65
+ two_words_connector: " and ",
66
+ last_word_connector: ", and "
67
+ }
68
+ if options[:locale] != false && defined?(I18n)
69
+ i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
70
+ default_connectors.merge!(i18n_connectors)
71
+ end
72
+ options = default_connectors.merge!(options)
73
+
74
+ case length
75
+ when 0
76
+ +""
77
+ when 1
78
+ +"#{self[0]}"
79
+ when 2
80
+ +"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
81
+ else
82
+ +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
83
+ end
84
+ end
85
+
86
+ # Extends <tt>Array#to_s</tt> to convert a collection of elements into a
87
+ # comma separated id list if <tt>:db</tt> argument is given as the format.
88
+ #
89
+ # This method is aliased to <tt>to_formatted_s</tt>.
90
+ #
91
+ # Blog.all.to_fs(:db) # => "1,2,3"
92
+ # Blog.none.to_fs(:db) # => "null"
93
+ # [1,2].to_fs # => "[1, 2]"
94
+ def to_fs(format = :default)
95
+ case format
96
+ when :db
97
+ if empty?
98
+ "null"
99
+ else
100
+ collect(&:id).join(",")
101
+ end
102
+ else
103
+ to_s
104
+ end
105
+ end
106
+ alias_method :to_formatted_s, :to_fs
107
+
108
+ # Returns a string that represents the array in XML by invoking +to_xml+
109
+ # on each element. Active Record collections delegate their representation
110
+ # in XML to this method.
111
+ #
112
+ # All elements are expected to respond to +to_xml+, if any of them does
113
+ # not then an exception is raised.
114
+ #
115
+ # The root node reflects the class name of the first element in plural
116
+ # if all elements belong to the same type and that's not Hash:
117
+ #
118
+ # customer.projects.to_xml
119
+ #
120
+ # <?xml version="1.0" encoding="UTF-8"?>
121
+ # <projects type="array">
122
+ # <project>
123
+ # <amount type="decimal">20000.0</amount>
124
+ # <customer-id type="integer">1567</customer-id>
125
+ # <deal-date type="date">2008-04-09</deal-date>
126
+ # ...
127
+ # </project>
128
+ # <project>
129
+ # <amount type="decimal">57230.0</amount>
130
+ # <customer-id type="integer">1567</customer-id>
131
+ # <deal-date type="date">2008-04-15</deal-date>
132
+ # ...
133
+ # </project>
134
+ # </projects>
135
+ #
136
+ # Otherwise the root element is "objects":
137
+ #
138
+ # [{ foo: 1, bar: 2}, { baz: 3}].to_xml
139
+ #
140
+ # <?xml version="1.0" encoding="UTF-8"?>
141
+ # <objects type="array">
142
+ # <object>
143
+ # <bar type="integer">2</bar>
144
+ # <foo type="integer">1</foo>
145
+ # </object>
146
+ # <object>
147
+ # <baz type="integer">3</baz>
148
+ # </object>
149
+ # </objects>
150
+ #
151
+ # If the collection is empty the root element is "nil-classes" by default:
152
+ #
153
+ # [].to_xml
154
+ #
155
+ # <?xml version="1.0" encoding="UTF-8"?>
156
+ # <nil-classes type="array"/>
157
+ #
158
+ # To ensure a meaningful root element use the <tt>:root</tt> option:
159
+ #
160
+ # customer_with_no_projects.projects.to_xml(root: 'projects')
161
+ #
162
+ # <?xml version="1.0" encoding="UTF-8"?>
163
+ # <projects type="array"/>
164
+ #
165
+ # By default name of the node for the children of root is <tt>root.singularize</tt>.
166
+ # You can change it with the <tt>:children</tt> option.
167
+ #
168
+ # The +options+ hash is passed downwards:
169
+ #
170
+ # Message.all.to_xml(skip_types: true)
171
+ #
172
+ # <?xml version="1.0" encoding="UTF-8"?>
173
+ # <messages>
174
+ # <message>
175
+ # <created-at>2008-03-07T09:58:18+01:00</created-at>
176
+ # <id>1</id>
177
+ # <name>1</name>
178
+ # <updated-at>2008-03-07T09:58:18+01:00</updated-at>
179
+ # <user-id>1</user-id>
180
+ # </message>
181
+ # </messages>
182
+ #
183
+ def to_xml(options = {})
184
+ require "active_support/builder" unless defined?(Builder::XmlMarkup)
185
+
186
+ options = options.dup
187
+ options[:indent] ||= 2
188
+ options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
189
+ options[:root] ||= \
190
+ if first.class != Hash && all?(first.class)
191
+ underscored = ActiveSupport::Inflector.underscore(first.class.name)
192
+ ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
193
+ else
194
+ "objects"
195
+ end
196
+
197
+ builder = options[:builder]
198
+ builder.instruct! unless options.delete(:skip_instruct)
199
+
200
+ root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
201
+ children = options.delete(:children) || root.singularize
202
+ attributes = options[:skip_types] ? {} : { type: "array" }
203
+
204
+ if empty?
205
+ builder.tag!(root, attributes)
206
+ else
207
+ builder.tag!(root, attributes) do
208
+ each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
209
+ yield builder if block_given?
27
210
  end
28
211
  end
29
212
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Removes and returns the elements for which the block returns a true value.
5
+ # If no block is given, an Enumerator is returned instead.
6
+ #
7
+ # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8
+ # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
9
+ # numbers # => [0, 2, 4, 6, 8]
10
+ def extract!
11
+ return to_enum(:extract!) { size } unless block_given?
12
+
13
+ extracted_elements = []
14
+
15
+ reject! do |element|
16
+ extracted_elements << element if yield(element)
17
+ end
18
+
19
+ extracted_elements
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ # By default, only instances of Hash itself are extractable.
5
+ # Subclasses of Hash may implement this method and return
6
+ # true to declare themselves as extractable. If a Hash
7
+ # is extractable, Array#extract_options! pops it from
8
+ # the Array when it is the last element of the Array.
9
+ def extractable_options?
10
+ instance_of?(Hash)
11
+ end
12
+ end
13
+
14
+ class Array
15
+ # Extracts options from a set of arguments. Removes and returns the last
16
+ # element in the array if it's a hash, otherwise returns a blank hash.
17
+ #
18
+ # def options(*args)
19
+ # args.extract_options!
20
+ # end
21
+ #
22
+ # options(1, 2) # => {}
23
+ # options(1, 2, a: :b) # => {:a=>:b}
24
+ def extract_options!
25
+ if last.is_a?(Hash) && last.extractable_options?
26
+ pop
27
+ else
28
+ {}
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Splits or iterates over the array in groups of size +number+,
5
+ # padding any remaining slots with +fill_with+ unless it is +false+.
6
+ #
7
+ # %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
8
+ # ["1", "2", "3"]
9
+ # ["4", "5", "6"]
10
+ # ["7", "8", "9"]
11
+ # ["10", nil, nil]
12
+ #
13
+ # %w(1 2 3 4 5).in_groups_of(2, '&nbsp;') {|group| p group}
14
+ # ["1", "2"]
15
+ # ["3", "4"]
16
+ # ["5", "&nbsp;"]
17
+ #
18
+ # %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
19
+ # ["1", "2"]
20
+ # ["3", "4"]
21
+ # ["5"]
22
+ def in_groups_of(number, fill_with = nil, &block)
23
+ if number.to_i <= 0
24
+ raise ArgumentError,
25
+ "Group size must be a positive integer, was #{number.inspect}"
26
+ end
27
+
28
+ if fill_with == false
29
+ collection = self
30
+ else
31
+ # size % number gives how many extra we have;
32
+ # subtracting from number gives how many to add;
33
+ # modulo number ensures we don't add group of just fill.
34
+ padding = (number - size % number) % number
35
+ collection = dup.concat(Array.new(padding, fill_with))
36
+ end
37
+
38
+ if block_given?
39
+ collection.each_slice(number, &block)
40
+ else
41
+ collection.each_slice(number).to_a
42
+ end
43
+ end
44
+
45
+ # Splits or iterates over the array in +number+ of groups, padding any
46
+ # remaining slots with +fill_with+ unless it is +false+.
47
+ #
48
+ # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
49
+ # ["1", "2", "3", "4"]
50
+ # ["5", "6", "7", nil]
51
+ # ["8", "9", "10", nil]
52
+ #
53
+ # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
54
+ # ["1", "2", "3", "4"]
55
+ # ["5", "6", "7", "&nbsp;"]
56
+ # ["8", "9", "10", "&nbsp;"]
57
+ #
58
+ # %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
59
+ # ["1", "2", "3"]
60
+ # ["4", "5"]
61
+ # ["6", "7"]
62
+ def in_groups(number, fill_with = nil, &block)
63
+ # size.div number gives minor group size;
64
+ # size % number gives how many objects need extra accommodation;
65
+ # each group hold either division or division + 1 items.
66
+ division = size.div number
67
+ modulo = size % number
68
+
69
+ # create a new array avoiding dup
70
+ groups = []
71
+ start = 0
72
+
73
+ number.times do |index|
74
+ length = division + (modulo > 0 && modulo > index ? 1 : 0)
75
+ groups << last_group = slice(start, length)
76
+ last_group << fill_with if fill_with != false &&
77
+ modulo > 0 && length == division
78
+ start += length
79
+ end
80
+
81
+ if block_given?
82
+ groups.each(&block)
83
+ else
84
+ groups
85
+ end
86
+ end
87
+
88
+ # Divides the array into one or more subarrays based on a delimiting +value+
89
+ # or the result of an optional block.
90
+ #
91
+ # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
92
+ # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
93
+ def split(value = nil, &block)
94
+ arr = dup
95
+ result = []
96
+ if block_given?
97
+ while (idx = arr.index(&block))
98
+ result << arr.shift(idx)
99
+ arr.shift
100
+ end
101
+ else
102
+ while (idx = arr.index(value))
103
+ result << arr.shift(idx)
104
+ arr.shift
105
+ end
106
+ end
107
+ result << arr
108
+ end
109
+ end
@@ -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 ActiveSupport::ArrayInquirer object, which gives a
7
+ # friendlier way 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,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
@@ -1,5 +1,9 @@
1
- require File.dirname(__FILE__) + '/array/conversions'
1
+ # frozen_string_literal: true
2
2
 
3
- class Array #:nodoc:
4
- include ActiveSupport::CoreExtensions::Array::Conversions
5
- end
3
+ require_relative "array/wrap"
4
+ require_relative "array/access"
5
+ require_relative "array/conversions"
6
+ require_relative "array/extract"
7
+ require_relative "array/extract_options"
8
+ require_relative "array/grouping"
9
+ require_relative "array/inquiry"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Remove this file from activesupport/lib/active_support/core_ext.rb when deleting the deprecation.
4
+ ActiveSupport.deprecator.warn <<~TEXT
5
+ active_support/core_ext/benchmark.rb is deprecated and will be removed in Rails 8.2 without replacement.
6
+ TEXT
@@ -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,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "big_decimal/conversions"
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
+ require "active_support/class_attribute"
5
+
6
+ class Class
7
+ # Declare a class-level attribute whose value is inheritable by subclasses.
8
+ # Subclasses can change their own value and it will not impact parent class.
9
+ #
10
+ # ==== Options
11
+ #
12
+ # * <tt>:instance_reader</tt> - Sets the instance reader method (defaults to true).
13
+ # * <tt>:instance_writer</tt> - Sets the instance writer method (defaults to true).
14
+ # * <tt>:instance_accessor</tt> - Sets both instance methods (defaults to true).
15
+ # * <tt>:instance_predicate</tt> - Sets a predicate method (defaults to true).
16
+ # * <tt>:default</tt> - Sets a default value for the attribute (defaults to nil).
17
+ #
18
+ # ==== Examples
19
+ #
20
+ # class Base
21
+ # class_attribute :setting
22
+ # end
23
+ #
24
+ # class Subclass < Base
25
+ # end
26
+ #
27
+ # Base.setting = true
28
+ # Subclass.setting # => true
29
+ # Subclass.setting = false
30
+ # Subclass.setting # => false
31
+ # Base.setting # => true
32
+ #
33
+ # In the above case as long as Subclass does not assign a value to setting
34
+ # by performing <tt>Subclass.setting = _something_</tt>, <tt>Subclass.setting</tt>
35
+ # would read value assigned to parent class. Once Subclass assigns a value then
36
+ # the value assigned by Subclass would be returned.
37
+ #
38
+ # This matches normal Ruby method inheritance: think of writing an attribute
39
+ # on a subclass as overriding the reader method. However, you need to be aware
40
+ # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
41
+ # In such cases, you don't want to do changes in place. Instead use setters:
42
+ #
43
+ # Base.setting = []
44
+ # Base.setting # => []
45
+ # Subclass.setting # => []
46
+ #
47
+ # # Appending in child changes both parent and child because it is the same object:
48
+ # Subclass.setting << :foo
49
+ # Base.setting # => [:foo]
50
+ # Subclass.setting # => [:foo]
51
+ #
52
+ # # Use setters to not propagate changes:
53
+ # Base.setting = []
54
+ # Subclass.setting += [:foo]
55
+ # Base.setting # => []
56
+ # Subclass.setting # => [:foo]
57
+ #
58
+ # For convenience, an instance predicate method is defined as well.
59
+ # To skip it, pass <tt>instance_predicate: false</tt>.
60
+ #
61
+ # Subclass.setting? # => false
62
+ #
63
+ # Instances may overwrite the class value in the same way:
64
+ #
65
+ # Base.setting = true
66
+ # object = Base.new
67
+ # object.setting # => true
68
+ # object.setting = false
69
+ # object.setting # => false
70
+ # Base.setting # => true
71
+ #
72
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
73
+ #
74
+ # object.setting # => NoMethodError
75
+ # object.setting? # => NoMethodError
76
+ #
77
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
78
+ #
79
+ # object.setting = false # => NoMethodError
80
+ #
81
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
82
+ #
83
+ # To set a default value for the attribute, pass <tt>default:</tt>, like so:
84
+ #
85
+ # class_attribute :settings, default: {}
86
+ def class_attribute(*attrs, instance_accessor: true,
87
+ instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil
88
+ )
89
+ class_methods, methods = [], []
90
+ attrs.each do |name|
91
+ unless name.is_a?(Symbol) || name.is_a?(String)
92
+ raise TypeError, "#{name.inspect} is not a symbol nor a string"
93
+ end
94
+
95
+ name = name.to_sym
96
+ namespaced_name = :"__class_attr_#{name}"
97
+ ::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, default)
98
+
99
+ class_methods << "def #{name}; #{namespaced_name}; end"
100
+ class_methods << "def #{name}=(value); self.#{namespaced_name} = value; end"
101
+
102
+ if singleton_class?
103
+ methods << <<~RUBY if instance_reader
104
+ silence_redefinition_of_method(:#{name})
105
+ def #{name}
106
+ self.singleton_class.#{name}
107
+ end
108
+ RUBY
109
+ else
110
+ methods << <<~RUBY if instance_reader
111
+ silence_redefinition_of_method def #{name}
112
+ if defined?(@#{name})
113
+ @#{name}
114
+ else
115
+ self.class.#{name}
116
+ end
117
+ end
118
+ RUBY
119
+ end
120
+
121
+ methods << <<~RUBY if instance_writer
122
+ silence_redefinition_of_method(:#{name}=)
123
+ attr_writer :#{name}
124
+ RUBY
125
+
126
+ if instance_predicate
127
+ class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
128
+ if instance_reader
129
+ methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
130
+ end
131
+ end
132
+ end
133
+
134
+ location = caller_locations(1, 1).first
135
+ class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno)
136
+ end
137
+ 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,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/descendants_tracker"
4
+
5
+ class Class
6
+ # Returns an array with all classes that are < than its receiver.
7
+ #
8
+ # class C; end
9
+ # C.descendants # => []
10
+ #
11
+ # class B < C; end
12
+ # C.descendants # => [B]
13
+ #
14
+ # class A < B; end
15
+ # C.descendants # => [B, A]
16
+ #
17
+ # class D < C; end
18
+ # C.descendants # => [B, A, D]
19
+ def descendants
20
+ subclasses.concat(subclasses.flat_map(&:descendants))
21
+ end
22
+
23
+ prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
24
+ end