activesupport 4.0.12 → 7.0.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (295) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +249 -501
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +41 -13
  9. data/lib/active_support/benchmarkable.rb +7 -15
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +96 -74
  12. data/lib/active_support/cache/mem_cache_store.rb +211 -103
  13. data/lib/active_support/cache/memory_store.rb +90 -58
  14. data/lib/active_support/cache/null_store.rb +19 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +468 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +86 -83
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  18. data/lib/active_support/cache.rb +580 -241
  19. data/lib/active_support/callbacks.rb +812 -425
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +103 -14
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
  23. data/lib/active_support/concurrency/share_lock.rb +226 -0
  24. data/lib/active_support/configurable.rb +21 -19
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +47 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +35 -44
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +26 -16
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  34. data/lib/active_support/core_ext/array.rb +10 -7
  35. data/lib/active_support/core_ext/benchmark.rb +5 -3
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  37. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  38. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  40. data/lib/active_support/core_ext/class/subclasses.rb +25 -26
  41. data/lib/active_support/core_ext/class.rb +4 -4
  42. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  43. data/lib/active_support/core_ext/date/blank.rb +14 -0
  44. data/lib/active_support/core_ext/date/calculations.rb +31 -18
  45. data/lib/active_support/core_ext/date/conversions.rb +43 -32
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +5 -34
  48. data/lib/active_support/core_ext/date.rb +7 -4
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +8 -4
  59. data/lib/active_support/core_ext/digest/uuid.rb +79 -0
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +249 -17
  62. data/lib/active_support/core_ext/file/atomic.rb +41 -32
  63. data/lib/active_support/core_ext/file.rb +3 -1
  64. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +14 -5
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +39 -56
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -23
  72. data/lib/active_support/core_ext/hash.rb +10 -8
  73. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +11 -33
  76. data/lib/active_support/core_ext/integer.rb +5 -3
  77. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  80. data/lib/active_support/core_ext/kernel.rb +5 -4
  81. data/lib/active_support/core_ext/load_error.rb +5 -21
  82. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  83. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  84. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
  87. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  88. data/lib/active_support/core_ext/module/delegation.rb +172 -45
  89. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  90. data/lib/active_support/core_ext/module/introspection.rb +23 -38
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -10
  94. data/lib/active_support/core_ext/name_error.rb +45 -4
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  99. data/lib/active_support/core_ext/numeric.rb +6 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +70 -20
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  104. data/lib/active_support/core_ext/object/duplicable.rb +17 -47
  105. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +244 -0
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  110. data/lib/active_support/core_ext/object/try.rb +106 -26
  111. data/lib/active_support/core_ext/object/with_options.rb +64 -5
  112. data/lib/active_support/core_ext/object.rb +14 -12
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +18 -17
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  121. data/lib/active_support/core_ext/range.rb +7 -4
  122. data/lib/active_support/core_ext/regexp.rb +10 -1
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string/access.rb +42 -51
  125. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  126. data/lib/active_support/core_ext/string/conversions.rb +18 -13
  127. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  128. data/lib/active_support/core_ext/string/filters.rb +97 -7
  129. data/lib/active_support/core_ext/string/indent.rb +6 -4
  130. data/lib/active_support/core_ext/string/inflections.rb +106 -25
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  133. data/lib/active_support/core_ext/string/output_safety.rb +227 -54
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +6 -5
  136. data/lib/active_support/core_ext/string/zones.rb +4 -1
  137. data/lib/active_support/core_ext/string.rb +15 -13
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  141. data/lib/active_support/core_ext/time/calculations.rb +178 -116
  142. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  143. data/lib/active_support/core_ext/time/conversions.rb +37 -25
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +44 -42
  146. data/lib/active_support/core_ext/time.rb +8 -5
  147. data/lib/active_support/core_ext/uri.rb +4 -25
  148. data/lib/active_support/core_ext.rb +4 -2
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +3 -1
  152. data/lib/active_support/dependencies/interlock.rb +49 -0
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +71 -696
  155. data/lib/active_support/deprecation/behaviors.rb +65 -16
  156. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  159. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
  161. data/lib/active_support/deprecation/reporting.rb +81 -18
  162. data/lib/active_support/deprecation.rb +19 -11
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  166. data/lib/active_support/duration/iso8601_serializer.rb +67 -0
  167. data/lib/active_support/duration.rb +437 -39
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +117 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +170 -0
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +151 -0
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +8 -0
  178. data/lib/active_support/file_update_checker.rb +62 -37
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +17 -0
  181. data/lib/active_support/gzip.rb +7 -5
  182. data/lib/active_support/hash_with_indifferent_access.rb +207 -54
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +10 -6
  185. data/lib/active_support/i18n_railtie.rb +48 -19
  186. data/lib/active_support/inflections.rb +19 -12
  187. data/lib/active_support/inflector/inflections.rb +97 -37
  188. data/lib/active_support/inflector/methods.rb +192 -157
  189. data/lib/active_support/inflector/transliterate.rb +83 -33
  190. data/lib/active_support/inflector.rb +7 -5
  191. data/lib/active_support/isolated_execution_state.rb +64 -0
  192. data/lib/active_support/json/decoding.rb +37 -42
  193. data/lib/active_support/json/encoding.rb +93 -293
  194. data/lib/active_support/json.rb +4 -2
  195. data/lib/active_support/key_generator.rb +30 -47
  196. data/lib/active_support/lazy_load_hooks.rb +54 -21
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +10 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  200. data/lib/active_support/log_subscriber.rb +61 -18
  201. data/lib/active_support/logger.rb +40 -4
  202. data/lib/active_support/logger_silence.rb +17 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +69 -0
  204. data/lib/active_support/message_encryptor.rb +178 -55
  205. data/lib/active_support/message_verifier.rb +195 -26
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +45 -92
  210. data/lib/active_support/multibyte/unicode.rb +44 -377
  211. data/lib/active_support/multibyte.rb +5 -3
  212. data/lib/active_support/notifications/fanout.rb +177 -44
  213. data/lib/active_support/notifications/instrumenter.rb +117 -17
  214. data/lib/active_support/notifications.rb +106 -39
  215. data/lib/active_support/number_helper/number_converter.rb +181 -0
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  223. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  224. data/lib/active_support/number_helper.rb +152 -394
  225. data/lib/active_support/option_merger.rb +18 -5
  226. data/lib/active_support/ordered_hash.rb +8 -6
  227. data/lib/active_support/ordered_options.rb +43 -7
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +24 -11
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +10 -11
  232. data/lib/active_support/railtie.rb +118 -12
  233. data/lib/active_support/reloader.rb +130 -0
  234. data/lib/active_support/rescuable.rb +112 -57
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +38 -0
  238. data/lib/active_support/string_inquirer.rb +11 -4
  239. data/lib/active_support/subscriber.rb +109 -39
  240. data/lib/active_support/tagged_logging.rb +54 -17
  241. data/lib/active_support/test_case.rb +121 -37
  242. data/lib/active_support/testing/assertions.rb +177 -39
  243. data/lib/active_support/testing/autorun.rb +5 -3
  244. data/lib/active_support/testing/constant_lookup.rb +3 -6
  245. data/lib/active_support/testing/declarative.rb +10 -22
  246. data/lib/active_support/testing/deprecation.rb +65 -11
  247. data/lib/active_support/testing/file_fixtures.rb +38 -0
  248. data/lib/active_support/testing/isolation.rb +56 -87
  249. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  255. data/lib/active_support/testing/stream.rb +41 -0
  256. data/lib/active_support/testing/tagged_logging.rb +6 -4
  257. data/lib/active_support/testing/time_helpers.rb +246 -0
  258. data/lib/active_support/time.rb +13 -13
  259. data/lib/active_support/time_with_zone.rb +315 -90
  260. data/lib/active_support/values/time_zone.rb +306 -135
  261. data/lib/active_support/version.rb +6 -7
  262. data/lib/active_support/xml_mini/jdom.rb +117 -115
  263. data/lib/active_support/xml_mini/libxml.rb +22 -21
  264. data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
  265. data/lib/active_support/xml_mini/nokogiri.rb +19 -19
  266. data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
  267. data/lib/active_support/xml_mini/rexml.rb +25 -17
  268. data/lib/active_support/xml_mini.rb +67 -56
  269. data/lib/active_support.rb +58 -3
  270. metadata +125 -66
  271. data/lib/active_support/basic_object.rb +0 -11
  272. data/lib/active_support/buffered_logger.rb +0 -21
  273. data/lib/active_support/concurrency/latch.rb +0 -27
  274. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  275. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  276. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  277. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  278. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  279. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  280. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  281. data/lib/active_support/core_ext/logger.rb +0 -67
  282. data/lib/active_support/core_ext/marshal.rb +0 -21
  283. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  284. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  285. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  286. data/lib/active_support/core_ext/proc.rb +0 -17
  287. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  288. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  289. data/lib/active_support/core_ext/struct.rb +0 -6
  290. data/lib/active_support/core_ext/thread.rb +0 -79
  291. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  292. data/lib/active_support/file_watcher.rb +0 -36
  293. data/lib/active_support/json/variable.rb +0 -18
  294. data/lib/active_support/testing/pending.rb +0 -14
  295. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Returns the tail of the array from +position+.
3
5
  #
@@ -5,6 +7,8 @@ class Array
5
7
  # %w( a b c d ).from(2) # => ["c", "d"]
6
8
  # %w( a b c d ).from(10) # => []
7
9
  # %w().from(0) # => []
10
+ # %w( a b c d ).from(-2) # => ["c", "d"]
11
+ # %w( a b c ).from(-10) # => []
8
12
  def from(position)
9
13
  self[position, length] || []
10
14
  end
@@ -15,9 +19,35 @@ class Array
15
19
  # %w( a b c d ).to(2) # => ["a", "b", "c"]
16
20
  # %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
17
21
  # %w().to(0) # => []
22
+ # %w( a b c d ).to(-2) # => ["a", "b", "c"]
23
+ # %w( a b c ).to(-10) # => []
18
24
  def to(position)
19
- first position + 1
25
+ if position >= 0
26
+ take position + 1
27
+ else
28
+ self[0..position]
29
+ end
30
+ end
31
+
32
+ # Returns a new array that includes the passed elements.
33
+ #
34
+ # [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
35
+ # [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
36
+ def including(*elements)
37
+ self + elements.flatten(1)
38
+ end
39
+
40
+ # Returns a copy of the Array excluding the specified elements.
41
+ #
42
+ # ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
43
+ # [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
44
+ #
45
+ # Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
46
+ # instead of <tt>Array#reject</tt> for performance reasons.
47
+ def excluding(*elements)
48
+ self - elements.flatten(1)
20
49
  end
50
+ alias :without :excluding
21
51
 
22
52
  # Equal to <tt>self[1]</tt>.
23
53
  #
@@ -48,7 +78,23 @@ class Array
48
78
  end
49
79
 
50
80
  # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
81
+ #
82
+ # (1..42).to_a.forty_two # => 42
51
83
  def forty_two
52
84
  self[41]
53
85
  end
86
+
87
+ # Equal to <tt>self[-3]</tt>.
88
+ #
89
+ # %w( a b c d e ).third_to_last # => "c"
90
+ def third_to_last
91
+ self[-3]
92
+ end
93
+
94
+ # Equal to <tt>self[-2]</tt>.
95
+ #
96
+ # %w( a b c d e ).second_to_last # => "d"
97
+ def second_to_last
98
+ self[-2]
99
+ end
54
100
  end
@@ -1,8 +1,10 @@
1
- require 'active_support/xml_mini'
2
- require 'active_support/core_ext/hash/keys'
3
- require 'active_support/core_ext/string/inflections'
4
- require 'active_support/core_ext/object/to_param'
5
- require 'active_support/core_ext/object/to_query'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/xml_mini"
4
+ require "active_support/core_ext/hash/keys"
5
+ require "active_support/core_ext/string/inflections"
6
+ require "active_support/core_ext/object/to_param"
7
+ require "active_support/core_ext/object/to_query"
6
8
 
7
9
  class Array
8
10
  # Converts the array to a comma-separated sentence where the last element is
@@ -14,12 +16,12 @@ class Array
14
16
  #
15
17
  # ==== Options
16
18
  #
17
- # * <tt>:words_connector</tt> - The sign or word used to join the elements
18
- # in arrays with two or more elements (default: ", ").
19
- # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
20
- # in arrays with two elements (default: " and ").
19
+ # * <tt>:words_connector</tt> - The sign or word used to join all but the last
20
+ # element in arrays with three or more elements (default: ", ").
21
21
  # * <tt>:last_word_connector</tt> - The sign or word used to join the last element
22
22
  # in arrays with three or more elements (default: ", and ").
23
+ # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
24
+ # in arrays with two elements (default: " and ").
23
25
  # * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
24
26
  # the connector options defined on the 'support.array' namespace in the
25
27
  # corresponding dictionary file.
@@ -32,7 +34,7 @@ class Array
32
34
  # ['one', 'two', 'three'].to_sentence # => "one, two, and three"
33
35
  #
34
36
  # ['one', 'two'].to_sentence(passing: 'invalid option')
35
- # # => ArgumentError: Unknown key :passing
37
+ # # => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
36
38
  #
37
39
  # ['one', 'two'].to_sentence(two_words_connector: '-')
38
40
  # # => "one-two"
@@ -60,11 +62,11 @@ class Array
60
62
  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
61
63
 
62
64
  default_connectors = {
63
- :words_connector => ', ',
64
- :two_words_connector => ' and ',
65
- :last_word_connector => ', and '
65
+ words_connector: ", ",
66
+ two_words_connector: " and ",
67
+ last_word_connector: ", and "
66
68
  }
67
- if defined?(I18n)
69
+ if options[:locale] != false && defined?(I18n)
68
70
  i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
69
71
  default_connectors.merge!(i18n_connectors)
70
72
  end
@@ -72,49 +74,38 @@ class Array
72
74
 
73
75
  case length
74
76
  when 0
75
- ''
77
+ +""
76
78
  when 1
77
- self[0].to_s.dup
79
+ +"#{self[0]}"
78
80
  when 2
79
- "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
81
+ +"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
80
82
  else
81
- "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
83
+ +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
82
84
  end
83
85
  end
84
86
 
85
- # Converts a collection of elements into a formatted string by calling
86
- # <tt>to_s</tt> on all elements and joining them. Having this model:
87
- #
88
- # class Blog < ActiveRecord::Base
89
- # def to_s
90
- # title
91
- # end
92
- # end
93
- #
94
- # Blog.all.map(&:title) #=> ["First Post", "Second Post", "Third post"]
95
- #
96
- # <tt>to_formatted_s</tt> shows us:
97
- #
98
- # Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
87
+ # Extends <tt>Array#to_s</tt> to convert a collection of elements into a
88
+ # comma separated id list if <tt>:db</tt> argument is given as the format.
99
89
  #
100
- # Adding in the <tt>:db</tt> argument as the format yields a comma separated
101
- # id list:
90
+ # This method is aliased to <tt>to_formatted_s</tt>.
102
91
  #
103
- # Blog.all.to_formatted_s(:db) # => "1,2,3"
104
- def to_formatted_s(format = :default)
92
+ # Blog.all.to_fs(:db) # => "1,2,3"
93
+ # Blog.none.to_fs(:db) # => "null"
94
+ # [1,2].to_fs # => "[1, 2]"
95
+ def to_fs(format = :default)
105
96
  case format
106
97
  when :db
107
98
  if empty?
108
- 'null'
99
+ "null"
109
100
  else
110
- collect { |element| element.id }.join(',')
101
+ collect(&:id).join(",")
111
102
  end
112
103
  else
113
104
  to_default_s
114
105
  end
115
106
  end
107
+ alias_method :to_formatted_s, :to_fs
116
108
  alias_method :to_default_s, :to_s
117
- alias_method :to_s, :to_formatted_s
118
109
 
119
110
  # Returns a string that represents the array in XML by invoking +to_xml+
120
111
  # on each element. Active Record collections delegate their representation
@@ -192,17 +183,17 @@ class Array
192
183
  # </messages>
193
184
  #
194
185
  def to_xml(options = {})
195
- require 'active_support/builder' unless defined?(Builder)
186
+ require "active_support/builder" unless defined?(Builder::XmlMarkup)
196
187
 
197
188
  options = options.dup
198
189
  options[:indent] ||= 2
199
190
  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
200
191
  options[:root] ||= \
201
- if first.class != Hash && all? { |e| e.is_a?(first.class) }
192
+ if first.class != Hash && all?(first.class)
202
193
  underscored = ActiveSupport::Inflector.underscore(first.class.name)
203
- ActiveSupport::Inflector.pluralize(underscored).tr('/', '_')
194
+ ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
204
195
  else
205
- 'objects'
196
+ "objects"
206
197
  end
207
198
 
208
199
  builder = options[:builder]
@@ -210,7 +201,7 @@ class Array
210
201
 
211
202
  root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
212
203
  children = options.delete(:children) || root.singularize
213
- attributes = options[:skip_types] ? {} : { type: 'array' }
204
+ attributes = options[:skip_types] ? {} : { type: "array" }
214
205
 
215
206
  if empty?
216
207
  builder.tag!(root, attributes)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ NOT_SET = Object.new # :nodoc:
5
+ def to_s(format = NOT_SET) # :nodoc:
6
+ case format
7
+ when :db
8
+ ActiveSupport::Deprecation.warn(
9
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
10
+ )
11
+ if empty?
12
+ "null"
13
+ else
14
+ collect(&:id).join(",")
15
+ end
16
+ when NOT_SET
17
+ to_default_s
18
+ else
19
+ ActiveSupport::Deprecation.warn(
20
+ "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
21
+ )
22
+ to_default_s
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Array
4
+ # Removes and returns the elements for which the block returns a true value.
5
+ # If no block is given, an Enumerator is returned instead.
6
+ #
7
+ # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8
+ # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
9
+ # numbers # => [0, 2, 4, 6, 8]
10
+ def extract!
11
+ return to_enum(:extract!) { size } unless block_given?
12
+
13
+ extracted_elements = []
14
+
15
+ reject! do |element|
16
+ extracted_elements << element if yield(element)
17
+ end
18
+
19
+ extracted_elements
20
+ end
21
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Hash
2
4
  # By default, only instances of Hash itself are extractable.
3
5
  # Subclasses of Hash may implement this method and return
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Splits or iterates over the array in groups of size +number+,
3
5
  # padding any remaining slots with +fill_with+ unless it is +false+.
@@ -17,7 +19,12 @@ class Array
17
19
  # ["1", "2"]
18
20
  # ["3", "4"]
19
21
  # ["5"]
20
- def in_groups_of(number, fill_with = nil)
22
+ def in_groups_of(number, fill_with = nil, &block)
23
+ if number.to_i <= 0
24
+ raise ArgumentError,
25
+ "Group size must be a positive integer, was #{number.inspect}"
26
+ end
27
+
21
28
  if fill_with == false
22
29
  collection = self
23
30
  else
@@ -25,15 +32,13 @@ class Array
25
32
  # subtracting from number gives how many to add;
26
33
  # modulo number ensures we don't add group of just fill.
27
34
  padding = (number - size % number) % number
28
- collection = dup.concat([fill_with] * padding)
35
+ collection = dup.concat(Array.new(padding, fill_with))
29
36
  end
30
37
 
31
38
  if block_given?
32
- collection.each_slice(number) { |slice| yield(slice) }
39
+ collection.each_slice(number, &block)
33
40
  else
34
- groups = []
35
- collection.each_slice(number) { |group| groups << group }
36
- groups
41
+ collection.each_slice(number).to_a
37
42
  end
38
43
  end
39
44
 
@@ -54,8 +59,8 @@ class Array
54
59
  # ["1", "2", "3"]
55
60
  # ["4", "5"]
56
61
  # ["6", "7"]
57
- def in_groups(number, fill_with = nil)
58
- # size / number gives minor group size;
62
+ def in_groups(number, fill_with = nil, &block)
63
+ # size.div number gives minor group size;
59
64
  # size % number gives how many objects need extra accommodation;
60
65
  # each group hold either division or division + 1 items.
61
66
  division = size.div number
@@ -74,7 +79,7 @@ class Array
74
79
  end
75
80
 
76
81
  if block_given?
77
- groups.each { |g| yield(g) }
82
+ groups.each(&block)
78
83
  else
79
84
  groups
80
85
  end
@@ -86,14 +91,19 @@ class Array
86
91
  # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
87
92
  # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
88
93
  def split(value = nil, &block)
89
- inject([[]]) do |results, element|
90
- if block && block.call(element) || value == element
91
- results << []
92
- else
93
- results.last << element
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
94
105
  end
95
-
96
- results
97
106
  end
107
+ result << arr
98
108
  end
99
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 +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
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Wraps its argument in an array unless it is already an array (or array-like).
3
5
  #
4
6
  # Specifically:
5
7
  #
6
- # * If the argument is +nil+ an empty list is returned.
8
+ # * If the argument is +nil+ an empty array is returned.
7
9
  # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
8
10
  # * Otherwise, returns an array with the argument as its single element.
9
11
  #
@@ -15,12 +17,13 @@ class Array
15
17
  #
16
18
  # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
17
19
  # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
- # +nil+ right away.
20
+ # an array with the argument as its single element right away.
19
21
  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
20
22
  # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
21
- # * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+.
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.
22
25
  #
23
- # The second point is easily explained with some enumerables:
26
+ # The last point is easily explained with some enumerables:
24
27
  #
25
28
  # Array(foo: :bar) # => [[:foo, :bar]]
26
29
  # Array.wrap(foo: :bar) # => [{:foo=>:bar}]
@@ -1,7 +1,10 @@
1
- require 'active_support/core_ext/array/wrap'
2
- require 'active_support/core_ext/array/access'
3
- require 'active_support/core_ext/array/uniq_by'
4
- require 'active_support/core_ext/array/conversions'
5
- require 'active_support/core_ext/array/extract_options'
6
- require 'active_support/core_ext/array/grouping'
7
- require 'active_support/core_ext/array/prepend_and_append'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
4
+ require "active_support/core_ext/array/access"
5
+ require "active_support/core_ext/array/conversions"
6
+ require "active_support/core_ext/array/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
7
+ require "active_support/core_ext/array/extract"
8
+ require "active_support/core_ext/array/extract_options"
9
+ require "active_support/core_ext/array/grouping"
10
+ require "active_support/core_ext/array/inquiry"
@@ -1,4 +1,6 @@
1
- require 'benchmark'
1
+ # frozen_string_literal: true
2
+
3
+ require "benchmark"
2
4
 
3
5
  class << Benchmark
4
6
  # Benchmark realtime in milliseconds.
@@ -8,7 +10,7 @@ class << Benchmark
8
10
  #
9
11
  # Benchmark.ms { User.all }
10
12
  # # => 0.074
11
- def ms
12
- 1000 * realtime { yield }
13
+ def ms(&block)
14
+ 1000 * realtime(&block)
13
15
  end
14
16
  end
@@ -1,31 +1,14 @@
1
- require 'bigdecimal'
2
- require 'bigdecimal/util'
3
- require 'yaml'
1
+ # frozen_string_literal: true
4
2
 
5
- class BigDecimal
6
- YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
3
+ require "bigdecimal"
4
+ require "bigdecimal/util"
7
5
 
8
- def encode_with(coder)
9
- string = to_s
10
- coder.represent_scalar(nil, YAML_MAPPING[string] || string)
11
- end
12
-
13
- # Backport this method if it doesn't exist
14
- unless method_defined?(:to_d)
15
- def to_d
16
- self
17
- end
18
- end
19
-
20
- DEFAULT_STRING_FORMAT = 'F'
21
- def to_formatted_s(*args)
22
- if args[0].is_a?(Symbol)
23
- super
24
- else
25
- format = args[0] || DEFAULT_STRING_FORMAT
26
- _original_to_s(format)
6
+ module ActiveSupport
7
+ module BigDecimalWithDefaultFormat # :nodoc:
8
+ def to_s(format = "F")
9
+ super(format)
27
10
  end
28
11
  end
29
- alias_method :_original_to_s, :to_s
30
- alias_method :to_s, :to_formatted_s
31
12
  end
13
+
14
+ BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat)
@@ -1 +1,3 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/big_decimal/conversions"
@@ -1,11 +1,21 @@
1
- require 'active_support/core_ext/kernel/singleton_class'
2
- require 'active_support/core_ext/module/remove_method'
3
- require 'active_support/core_ext/array/extract_options'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
4
 
5
5
  class Class
6
6
  # Declare a class-level attribute whose value is inheritable by subclasses.
7
7
  # Subclasses can change their own value and it will not impact parent class.
8
8
  #
9
+ # ==== Options
10
+ #
11
+ # * <tt>:instance_reader</tt> - Sets the instance reader method (defaults to true).
12
+ # * <tt>:instance_writer</tt> - Sets the instance writer method (defaults to true).
13
+ # * <tt>:instance_accessor</tt> - Sets both instance methods (defaults to true).
14
+ # * <tt>:instance_predicate</tt> - Sets a predicate method (defaults to true).
15
+ # * <tt>:default</tt> - Sets a default value for the attribute (defaults to nil).
16
+ #
17
+ # ==== Examples
18
+ #
9
19
  # class Base
10
20
  # class_attribute :setting
11
21
  # end
@@ -20,14 +30,14 @@ class Class
20
30
  # Base.setting # => true
21
31
  #
22
32
  # In the above case as long as Subclass does not assign a value to setting
23
- # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
33
+ # by performing <tt>Subclass.setting = _something_</tt>, <tt>Subclass.setting</tt>
24
34
  # would read value assigned to parent class. Once Subclass assigns a value then
25
35
  # the value assigned by Subclass would be returned.
26
36
  #
27
37
  # This matches normal Ruby method inheritance: think of writing an attribute
28
38
  # on a subclass as overriding the reader method. However, you need to be aware
29
39
  # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
30
- # In such cases, you don't want to do changes in places but use setters:
40
+ # In such cases, you don't want to do changes in place. Instead use setters:
31
41
  #
32
42
  # Base.setting = []
33
43
  # Base.setting # => []
@@ -68,61 +78,54 @@ class Class
68
78
  # object.setting = false # => NoMethodError
69
79
  #
70
80
  # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
71
- def class_attribute(*attrs)
72
- options = attrs.extract_options!
73
- # double assignment is used to avoid "assigned but unused variable" warning
74
- instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
75
- instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
76
- instance_predicate = options.fetch(:instance_predicate, true)
81
+ #
82
+ # To set a default value for the attribute, pass <tt>default:</tt>, like so:
83
+ #
84
+ # class_attribute :settings, default: {}
85
+ def class_attribute(*attrs, instance_accessor: true,
86
+ instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
77
87
 
88
+ class_methods, methods = [], []
78
89
  attrs.each do |name|
79
- define_singleton_method(name) { nil }
80
- define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
90
+ unless name.is_a?(Symbol) || name.is_a?(String)
91
+ raise TypeError, "#{name.inspect} is not a symbol nor a string"
92
+ end
81
93
 
82
- ivar = "@#{name}"
94
+ class_methods << <<~RUBY # In case the method exists and is not public
95
+ silence_redefinition_of_method def #{name}
96
+ end
97
+ RUBY
83
98
 
84
- define_singleton_method("#{name}=") do |val|
85
- singleton_class.class_eval do
86
- remove_possible_method(name)
87
- define_method(name) { val }
99
+ methods << <<~RUBY if instance_reader
100
+ silence_redefinition_of_method def #{name}
101
+ defined?(@#{name}) ? @#{name} : self.class.#{name}
88
102
  end
103
+ RUBY
89
104
 
90
- if singleton_class?
91
- class_eval do
92
- remove_possible_method(name)
93
- define_method(name) do
94
- if instance_variable_defined? ivar
95
- instance_variable_get ivar
96
- else
97
- singleton_class.send name
98
- end
99
- end
100
- end
105
+ class_methods << <<~RUBY
106
+ silence_redefinition_of_method def #{name}=(value)
107
+ redefine_method(:#{name}) { value } if singleton_class?
108
+ redefine_singleton_method(:#{name}) { value }
109
+ value
101
110
  end
102
- val
103
- end
111
+ RUBY
112
+
113
+ methods << <<~RUBY if instance_writer
114
+ silence_redefinition_of_method(:#{name}=)
115
+ attr_writer :#{name}
116
+ RUBY
104
117
 
105
- if instance_reader
106
- remove_possible_method name
107
- define_method(name) do
108
- if instance_variable_defined?(ivar)
109
- instance_variable_get ivar
110
- else
111
- self.class.public_send name
112
- end
118
+ if instance_predicate
119
+ class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
120
+ if instance_reader
121
+ methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
113
122
  end
114
- define_method("#{name}?") { !!public_send(name) } if instance_predicate
115
123
  end
116
-
117
- attr_writer name if instance_writer
118
124
  end
119
- end
120
125
 
121
- private
126
+ location = caller_locations(1, 1).first
127
+ class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno)
122
128
 
123
- unless respond_to?(:singleton_class?)
124
- def singleton_class?
125
- ancestors.first != self
126
- end
127
- end
129
+ attrs.each { |name| public_send("#{name}=", default) }
130
+ end
128
131
  end