activesupport 4.2.11.1 → 6.0.3.1

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

Potentially problematic release.


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

Files changed (263) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -411
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -7
  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 +34 -6
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +58 -53
  12. data/lib/active_support/cache/mem_cache_store.rb +95 -91
  13. data/lib/active_support/cache/memory_store.rb +39 -36
  14. data/lib/active_support/cache/null_store.rb +11 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +75 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +331 -217
  19. data/lib/active_support/callbacks.rb +650 -592
  20. data/lib/active_support/concern.rb +35 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +226 -0
  23. data/lib/active_support/configurable.rb +13 -14
  24. data/lib/active_support/core_ext/array/access.rb +41 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  26. data/lib/active_support/core_ext/array/extract.rb +21 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  29. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
  31. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  32. data/lib/active_support/core_ext/array.rb +9 -6
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +45 -31
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  39. data/lib/active_support/core_ext/class.rb +4 -3
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +14 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  43. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +6 -4
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  50. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  53. data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
  54. data/lib/active_support/core_ext/date_time.rb +7 -5
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +114 -22
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/compact.rb +4 -23
  61. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  64. data/lib/active_support/core_ext/hash/except.rb +12 -9
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  66. data/lib/active_support/core_ext/hash/keys.rb +19 -42
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  68. data/lib/active_support/core_ext/hash/slice.rb +5 -27
  69. data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
  70. data/lib/active_support/core_ext/hash.rb +10 -9
  71. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  72. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  73. data/lib/active_support/core_ext/integer/time.rb +11 -18
  74. data/lib/active_support/core_ext/integer.rb +5 -3
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/kernel.rb +5 -5
  79. data/lib/active_support/core_ext/load_error.rb +3 -22
  80. data/lib/active_support/core_ext/marshal.rb +8 -8
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +133 -30
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +44 -19
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -7
  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 -11
  94. data/lib/active_support/core_ext/name_error.rb +22 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  99. data/lib/active_support/core_ext/numeric.rb +5 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +27 -3
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +51 -20
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  110. data/lib/active_support/core_ext/object/try.rb +81 -23
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/object.rb +14 -13
  113. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  115. data/lib/active_support/core_ext/range/each.rb +18 -17
  116. data/lib/active_support/core_ext/range/include_range.rb +7 -21
  117. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  119. data/lib/active_support/core_ext/range.rb +7 -4
  120. data/lib/active_support/core_ext/regexp.rb +2 -0
  121. data/lib/active_support/core_ext/securerandom.rb +45 -0
  122. data/lib/active_support/core_ext/string/access.rb +16 -6
  123. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  124. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  125. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  126. data/lib/active_support/core_ext/string/filters.rb +48 -6
  127. data/lib/active_support/core_ext/string/indent.rb +6 -4
  128. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  129. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  130. data/lib/active_support/core_ext/string/multibyte.rb +16 -7
  131. data/lib/active_support/core_ext/string/output_safety.rb +93 -40
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  133. data/lib/active_support/core_ext/string/strip.rb +6 -5
  134. data/lib/active_support/core_ext/string/zones.rb +4 -2
  135. data/lib/active_support/core_ext/string.rb +15 -13
  136. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  137. data/lib/active_support/core_ext/time/calculations.rb +115 -52
  138. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  139. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  140. data/lib/active_support/core_ext/time/zones.rb +41 -7
  141. data/lib/active_support/core_ext/time.rb +7 -6
  142. data/lib/active_support/core_ext/uri.rb +6 -7
  143. data/lib/active_support/core_ext.rb +3 -1
  144. data/lib/active_support/current_attributes.rb +203 -0
  145. data/lib/active_support/dependencies/autoload.rb +2 -0
  146. data/lib/active_support/dependencies/interlock.rb +57 -0
  147. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  148. data/lib/active_support/dependencies.rb +208 -166
  149. data/lib/active_support/deprecation/behaviors.rb +44 -11
  150. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  151. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  152. data/lib/active_support/deprecation/method_wrappers.rb +61 -21
  153. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  154. data/lib/active_support/deprecation/reporting.rb +32 -12
  155. data/lib/active_support/deprecation.rb +12 -9
  156. data/lib/active_support/descendants_tracker.rb +57 -9
  157. data/lib/active_support/digest.rb +20 -0
  158. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  159. data/lib/active_support/duration/iso8601_serializer.rb +53 -0
  160. data/lib/active_support/duration.rb +315 -40
  161. data/lib/active_support/encrypted_configuration.rb +45 -0
  162. data/lib/active_support/encrypted_file.rb +100 -0
  163. data/lib/active_support/evented_file_update_checker.rb +234 -0
  164. data/lib/active_support/execution_wrapper.rb +129 -0
  165. data/lib/active_support/executor.rb +8 -0
  166. data/lib/active_support/file_update_checker.rb +62 -37
  167. data/lib/active_support/gem_version.rb +6 -4
  168. data/lib/active_support/gzip.rb +7 -5
  169. data/lib/active_support/hash_with_indifferent_access.rb +129 -30
  170. data/lib/active_support/i18n.rb +9 -6
  171. data/lib/active_support/i18n_railtie.rb +50 -14
  172. data/lib/active_support/inflections.rb +13 -11
  173. data/lib/active_support/inflector/inflections.rb +58 -13
  174. data/lib/active_support/inflector/methods.rb +159 -145
  175. data/lib/active_support/inflector/transliterate.rb +84 -34
  176. data/lib/active_support/inflector.rb +7 -5
  177. data/lib/active_support/json/decoding.rb +32 -30
  178. data/lib/active_support/json/encoding.rb +17 -60
  179. data/lib/active_support/json.rb +4 -2
  180. data/lib/active_support/key_generator.rb +11 -43
  181. data/lib/active_support/lazy_load_hooks.rb +53 -20
  182. data/lib/active_support/locale/en.rb +33 -0
  183. data/lib/active_support/locale/en.yml +2 -0
  184. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  185. data/lib/active_support/log_subscriber.rb +44 -19
  186. data/lib/active_support/logger.rb +9 -23
  187. data/lib/active_support/logger_silence.rb +32 -14
  188. data/lib/active_support/logger_thread_safe_level.rb +32 -8
  189. data/lib/active_support/message_encryptor.rb +166 -53
  190. data/lib/active_support/message_verifier.rb +149 -16
  191. data/lib/active_support/messages/metadata.rb +72 -0
  192. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  193. data/lib/active_support/messages/rotator.rb +56 -0
  194. data/lib/active_support/multibyte/chars.rb +56 -63
  195. data/lib/active_support/multibyte/unicode.rb +56 -290
  196. data/lib/active_support/multibyte.rb +4 -2
  197. data/lib/active_support/notifications/fanout.rb +109 -22
  198. data/lib/active_support/notifications/instrumenter.rb +107 -16
  199. data/lib/active_support/notifications.rb +51 -10
  200. data/lib/active_support/number_helper/number_converter.rb +16 -15
  201. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
  202. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  203. data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
  204. data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
  205. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  206. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  207. data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
  208. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  209. data/lib/active_support/number_helper.rb +105 -68
  210. data/lib/active_support/option_merger.rb +24 -4
  211. data/lib/active_support/ordered_hash.rb +7 -5
  212. data/lib/active_support/ordered_options.rb +27 -5
  213. data/lib/active_support/parameter_filter.rb +128 -0
  214. data/lib/active_support/per_thread_registry.rb +9 -4
  215. data/lib/active_support/proxy_object.rb +2 -0
  216. data/lib/active_support/rails.rb +10 -8
  217. data/lib/active_support/railtie.rb +43 -9
  218. data/lib/active_support/reloader.rb +130 -0
  219. data/lib/active_support/rescuable.rb +108 -53
  220. data/lib/active_support/security_utils.rb +15 -11
  221. data/lib/active_support/string_inquirer.rb +11 -4
  222. data/lib/active_support/subscriber.rb +74 -30
  223. data/lib/active_support/tagged_logging.rb +25 -13
  224. data/lib/active_support/test_case.rb +107 -44
  225. data/lib/active_support/testing/assertions.rb +151 -20
  226. data/lib/active_support/testing/autorun.rb +4 -2
  227. data/lib/active_support/testing/constant_lookup.rb +2 -1
  228. data/lib/active_support/testing/declarative.rb +3 -1
  229. data/lib/active_support/testing/deprecation.rb +13 -10
  230. data/lib/active_support/testing/file_fixtures.rb +38 -0
  231. data/lib/active_support/testing/isolation.rb +35 -26
  232. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  233. data/lib/active_support/testing/parallelization.rb +134 -0
  234. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  235. data/lib/active_support/testing/stream.rb +43 -0
  236. data/lib/active_support/testing/tagged_logging.rb +3 -1
  237. data/lib/active_support/testing/time_helpers.rb +84 -20
  238. data/lib/active_support/time.rb +14 -12
  239. data/lib/active_support/time_with_zone.rb +179 -39
  240. data/lib/active_support/values/time_zone.rb +203 -63
  241. data/lib/active_support/version.rb +3 -1
  242. data/lib/active_support/xml_mini/jdom.rb +116 -115
  243. data/lib/active_support/xml_mini/libxml.rb +16 -13
  244. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  245. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  246. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  247. data/lib/active_support/xml_mini/rexml.rb +11 -9
  248. data/lib/active_support/xml_mini.rb +38 -46
  249. data/lib/active_support.rb +13 -11
  250. metadata +84 -26
  251. data/lib/active_support/concurrency/latch.rb +0 -27
  252. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  253. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  254. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  255. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  256. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  257. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  258. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  259. data/lib/active_support/core_ext/object/itself.rb +0 -15
  260. data/lib/active_support/core_ext/struct.rb +0 -6
  261. data/lib/active_support/core_ext/thread.rb +0 -86
  262. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  263. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,143 +1,136 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
2
- require 'active_support/number_helper'
1
+ # frozen_string_literal: true
3
2
 
4
- class Numeric
3
+ require "active_support/core_ext/big_decimal/conversions"
4
+ require "active_support/number_helper"
5
+ require "active_support/core_ext/module/deprecation"
5
6
 
6
- # Provides options for converting numbers into formatted strings.
7
- # Options are provided for phone numbers, currency, percentage,
8
- # precision, positional notation, file size and pretty printing.
9
- #
10
- # ==== Options
11
- #
12
- # For details on which formats use which options, see ActiveSupport::NumberHelper
13
- #
14
- # ==== Examples
15
- #
16
- # Phone Numbers:
17
- # 5551234.to_s(:phone) # => 555-1234
18
- # 1235551234.to_s(:phone) # => 123-555-1234
19
- # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234
20
- # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234
21
- # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
22
- # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234
23
- # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
24
- # # => +1.123.555.1234 x 1343
25
- #
26
- # Currency:
27
- # 1234567890.50.to_s(:currency) # => $1,234,567,890.50
28
- # 1234567890.506.to_s(:currency) # => $1,234,567,890.51
29
- # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
30
- # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51
31
- # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
32
- # # => ($1,234,567,890.50)
33
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
34
- # # => £1234567890,50
35
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
36
- # # => 1234567890,50 £
37
- #
38
- # Percentage:
39
- # 100.to_s(:percentage) # => 100.000%
40
- # 100.to_s(:percentage, precision: 0) # => 100%
41
- # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
42
- # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399%
43
- # 1000.to_s(:percentage, locale: :fr) # => 1 000,000%
44
- # 100.to_s(:percentage, format: '%n %') # => 100.000 %
45
- #
46
- # Delimited:
47
- # 12345678.to_s(:delimited) # => 12,345,678
48
- # 12345678.05.to_s(:delimited) # => 12,345,678.05
49
- # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678
50
- # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678
51
- # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05
52
- # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05
53
- # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
54
- # # => 98 765 432,98
55
- #
56
- # Rounded:
57
- # 111.2345.to_s(:rounded) # => 111.235
58
- # 111.2345.to_s(:rounded, precision: 2) # => 111.23
59
- # 13.to_s(:rounded, precision: 5) # => 13.00000
60
- # 389.32314.to_s(:rounded, precision: 0) # => 389
61
- # 111.2345.to_s(:rounded, significant: true) # => 111
62
- # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100
63
- # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000
64
- # 111.234.to_s(:rounded, locale: :fr) # => 111,234
65
- # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
66
- # # => 13
67
- # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3
68
- # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
69
- # # => 1.111,23
70
- #
71
- # Human-friendly size in Bytes:
72
- # 123.to_s(:human_size) # => 123 Bytes
73
- # 1234.to_s(:human_size) # => 1.21 KB
74
- # 12345.to_s(:human_size) # => 12.1 KB
75
- # 1234567.to_s(:human_size) # => 1.18 MB
76
- # 1234567890.to_s(:human_size) # => 1.15 GB
77
- # 1234567890123.to_s(:human_size) # => 1.12 TB
78
- # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB
79
- # 483989.to_s(:human_size, precision: 2) # => 470 KB
80
- # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
81
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
82
- # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
83
- #
84
- # Human-friendly format:
85
- # 123.to_s(:human) # => "123"
86
- # 1234.to_s(:human) # => "1.23 Thousand"
87
- # 12345.to_s(:human) # => "12.3 Thousand"
88
- # 1234567.to_s(:human) # => "1.23 Million"
89
- # 1234567890.to_s(:human) # => "1.23 Billion"
90
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
91
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
92
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
93
- # 489939.to_s(:human, precision: 2) # => "490 Thousand"
94
- # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
95
- # 1234567.to_s(:human, precision: 4,
96
- # significant: false) # => "1.2346 Million"
97
- # 1234567.to_s(:human, precision: 1,
98
- # separator: ',',
99
- # significant: false) # => "1,2 Million"
100
- def to_formatted_s(format = :default, options = {})
101
- case format
102
- when :phone
103
- return ActiveSupport::NumberHelper.number_to_phone(self, options)
104
- when :currency
105
- return ActiveSupport::NumberHelper.number_to_currency(self, options)
106
- when :percentage
107
- return ActiveSupport::NumberHelper.number_to_percentage(self, options)
108
- when :delimited
109
- return ActiveSupport::NumberHelper.number_to_delimited(self, options)
110
- when :rounded
111
- return ActiveSupport::NumberHelper.number_to_rounded(self, options)
112
- when :human
113
- return ActiveSupport::NumberHelper.number_to_human(self, options)
114
- when :human_size
115
- return ActiveSupport::NumberHelper.number_to_human_size(self, options)
116
- else
117
- self.to_default_s
118
- end
119
- end
120
-
121
- klasses = [Float, BigDecimal]
122
- # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
123
- if 0.class == Integer
124
- klasses << Integer
125
- else
126
- klasses << Fixnum << Bignum
127
- end
128
-
129
- klasses.each do |klass|
130
- klass.send(:alias_method, :to_default_s, :to_s)
131
-
132
- klass.send(:define_method, :to_s) do |*args|
133
- if args[0].is_a?(Symbol)
134
- format = args[0]
135
- options = args[1] || {}
136
-
137
- self.to_formatted_s(format, options)
7
+ module ActiveSupport
8
+ module NumericWithFormat
9
+ # Provides options for converting numbers into formatted strings.
10
+ # Options are provided for phone numbers, currency, percentage,
11
+ # precision, positional notation, file size and pretty printing.
12
+ #
13
+ # ==== Options
14
+ #
15
+ # For details on which formats use which options, see ActiveSupport::NumberHelper
16
+ #
17
+ # ==== Examples
18
+ #
19
+ # Phone Numbers:
20
+ # 5551234.to_s(:phone) # => "555-1234"
21
+ # 1235551234.to_s(:phone) # => "123-555-1234"
22
+ # 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
23
+ # 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
24
+ # 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
25
+ # 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
26
+ # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
27
+ # # => "+1.123.555.1234 x 1343"
28
+ #
29
+ # Currency:
30
+ # 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
31
+ # 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
32
+ # 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
33
+ # 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
34
+ # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
35
+ # # => "($1,234,567,890.50)"
36
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
37
+ # # => "&pound;1234567890,50"
38
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
39
+ # # => "1234567890,50 &pound;"
40
+ #
41
+ # Percentage:
42
+ # 100.to_s(:percentage) # => "100.000%"
43
+ # 100.to_s(:percentage, precision: 0) # => "100%"
44
+ # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
45
+ # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
46
+ # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
47
+ # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
48
+ #
49
+ # Delimited:
50
+ # 12345678.to_s(:delimited) # => "12,345,678"
51
+ # 12345678.05.to_s(:delimited) # => "12,345,678.05"
52
+ # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
53
+ # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
54
+ # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
55
+ # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
56
+ # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
57
+ # # => "98 765 432,98"
58
+ #
59
+ # Rounded:
60
+ # 111.2345.to_s(:rounded) # => "111.235"
61
+ # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
62
+ # 13.to_s(:rounded, precision: 5) # => "13.00000"
63
+ # 389.32314.to_s(:rounded, precision: 0) # => "389"
64
+ # 111.2345.to_s(:rounded, significant: true) # => "111"
65
+ # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
66
+ # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
67
+ # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
68
+ # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
69
+ # # => "13"
70
+ # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
71
+ # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
72
+ # # => "1.111,23"
73
+ #
74
+ # Human-friendly size in Bytes:
75
+ # 123.to_s(:human_size) # => "123 Bytes"
76
+ # 1234.to_s(:human_size) # => "1.21 KB"
77
+ # 12345.to_s(:human_size) # => "12.1 KB"
78
+ # 1234567.to_s(:human_size) # => "1.18 MB"
79
+ # 1234567890.to_s(:human_size) # => "1.15 GB"
80
+ # 1234567890123.to_s(:human_size) # => "1.12 TB"
81
+ # 1234567890123456.to_s(:human_size) # => "1.1 PB"
82
+ # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
83
+ # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
84
+ # 483989.to_s(:human_size, precision: 2) # => "470 KB"
85
+ # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
86
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
87
+ # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
88
+ #
89
+ # Human-friendly format:
90
+ # 123.to_s(:human) # => "123"
91
+ # 1234.to_s(:human) # => "1.23 Thousand"
92
+ # 12345.to_s(:human) # => "12.3 Thousand"
93
+ # 1234567.to_s(:human) # => "1.23 Million"
94
+ # 1234567890.to_s(:human) # => "1.23 Billion"
95
+ # 1234567890123.to_s(:human) # => "1.23 Trillion"
96
+ # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
97
+ # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
98
+ # 489939.to_s(:human, precision: 2) # => "490 Thousand"
99
+ # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
100
+ # 1234567.to_s(:human, precision: 4,
101
+ # significant: false) # => "1.2346 Million"
102
+ # 1234567.to_s(:human, precision: 1,
103
+ # separator: ',',
104
+ # significant: false) # => "1,2 Million"
105
+ def to_s(format = nil, options = nil)
106
+ case format
107
+ when nil
108
+ super()
109
+ when Integer, String
110
+ super(format)
111
+ when :phone
112
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
113
+ when :currency
114
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
115
+ when :percentage
116
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
117
+ when :delimited
118
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
119
+ when :rounded
120
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
121
+ when :human
122
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
123
+ when :human_size
124
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
125
+ when Symbol
126
+ super()
138
127
  else
139
- to_default_s(*args)
128
+ super(format)
140
129
  end
141
130
  end
142
131
  end
143
132
  end
133
+
134
+ Integer.prepend ActiveSupport::NumericWithFormat
135
+ Float.prepend ActiveSupport::NumericWithFormat
136
+ BigDecimal.prepend ActiveSupport::NumericWithFormat
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+
5
+ ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Numeric#positive? and Numeric#negative? natively, so requiring active_support/core_ext/numeric/inquiry is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
@@ -1,53 +1,65 @@
1
- require 'active_support/duration'
2
- require 'active_support/core_ext/time/calculations'
3
- require 'active_support/core_ext/time/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/duration"
4
+ require "active_support/core_ext/time/calculations"
5
+ require "active_support/core_ext/time/acts_like"
6
+ require "active_support/core_ext/date/calculations"
7
+ require "active_support/core_ext/date/acts_like"
4
8
 
5
9
  class Numeric
6
- # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
7
- #
8
- # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
9
- # as well as adding or subtracting their results from a Time object. For example:
10
- #
11
- # # equivalent to Time.current.advance(months: 1)
12
- # 1.month.from_now
10
+ # Returns a Duration instance matching the number of seconds provided.
13
11
  #
14
- # # equivalent to Time.current.advance(years: 2)
15
- # 2.years.from_now
16
- #
17
- # # equivalent to Time.current.advance(months: 4, years: 5)
18
- # (4.months + 5.years).from_now
12
+ # 2.seconds # => 2 seconds
19
13
  def seconds
20
- ActiveSupport::Duration.new(self, [[:seconds, self]])
14
+ ActiveSupport::Duration.seconds(self)
21
15
  end
22
16
  alias :second :seconds
23
17
 
18
+ # Returns a Duration instance matching the number of minutes provided.
19
+ #
20
+ # 2.minutes # => 2 minutes
24
21
  def minutes
25
- ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
22
+ ActiveSupport::Duration.minutes(self)
26
23
  end
27
24
  alias :minute :minutes
28
25
 
26
+ # Returns a Duration instance matching the number of hours provided.
27
+ #
28
+ # 2.hours # => 2 hours
29
29
  def hours
30
- ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
30
+ ActiveSupport::Duration.hours(self)
31
31
  end
32
32
  alias :hour :hours
33
33
 
34
+ # Returns a Duration instance matching the number of days provided.
35
+ #
36
+ # 2.days # => 2 days
34
37
  def days
35
- ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
38
+ ActiveSupport::Duration.days(self)
36
39
  end
37
40
  alias :day :days
38
41
 
42
+ # Returns a Duration instance matching the number of weeks provided.
43
+ #
44
+ # 2.weeks # => 2 weeks
39
45
  def weeks
40
- ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
46
+ ActiveSupport::Duration.weeks(self)
41
47
  end
42
48
  alias :week :weeks
43
49
 
50
+ # Returns a Duration instance matching the number of fortnights provided.
51
+ #
52
+ # 2.fortnights # => 4 weeks
44
53
  def fortnights
45
- ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
54
+ ActiveSupport::Duration.weeks(self * 2)
46
55
  end
47
56
  alias :fortnight :fortnights
48
57
 
49
- # Used with the standard time durations, like 1.hour.in_milliseconds --
50
- # so we can feed them to JavaScript functions like getTime().
58
+ # Returns the number of milliseconds equivalent to the seconds provided.
59
+ # Used with the standard time durations.
60
+ #
61
+ # 2.in_milliseconds # => 2000
62
+ # 1.hour.in_milliseconds # => 3600000
51
63
  def in_milliseconds
52
64
  self * 1000
53
65
  end
@@ -1,3 +1,5 @@
1
- require 'active_support/core_ext/numeric/bytes'
2
- require 'active_support/core_ext/numeric/time'
3
- require 'active_support/core_ext/numeric/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/numeric/bytes"
4
+ require "active_support/core_ext/numeric/time"
5
+ require "active_support/core_ext/numeric/conversions"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
4
  # A duck-type assistant method. For example, Active Support extends Date
3
5
  # to define an <tt>acts_like_date?</tt> method, and extends Time to define
@@ -5,6 +7,15 @@ class Object
5
7
  # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
6
8
  # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
7
9
  def acts_like?(duck)
8
- respond_to? :"acts_like_#{duck}?"
10
+ case duck
11
+ when :time
12
+ respond_to? :acts_like_time?
13
+ when :date
14
+ respond_to? :acts_like_date?
15
+ when :string
16
+ respond_to? :acts_like_string?
17
+ else
18
+ respond_to? :"acts_like_#{duck}?"
19
+ end
9
20
  end
10
21
  end
@@ -1,8 +1,10 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
2
4
 
3
5
  class Object
4
6
  # An object is blank if it's false, empty, or a whitespace string.
5
- # For example, +false+, '', ' ', +nil+, [], and {} are all blank.
7
+ # For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
6
8
  #
7
9
  # This simplifies
8
10
  #
@@ -100,6 +102,9 @@ end
100
102
 
101
103
  class String
102
104
  BLANK_RE = /\A[[:space:]]*\z/
105
+ ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
106
+ h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
107
+ end
103
108
 
104
109
  # A string is blank if it's empty or contains whitespaces only:
105
110
  #
@@ -114,7 +119,15 @@ class String
114
119
  #
115
120
  # @return [true, false]
116
121
  def blank?
117
- BLANK_RE === self
122
+ # The regexp that matches blank strings is expensive. For the case of empty
123
+ # strings we can speed up this method (~3.5x) with an empty? call. The
124
+ # penalty for the rest of strings is marginal.
125
+ empty? ||
126
+ begin
127
+ BLANK_RE.match?(self)
128
+ rescue Encoding::CompatibilityError
129
+ ENCODED_BLANKS[self.encoding].match?(self)
130
+ end
118
131
  end
119
132
  end
120
133
 
@@ -129,3 +142,14 @@ class Numeric #:nodoc:
129
142
  false
130
143
  end
131
144
  end
145
+
146
+ class Time #:nodoc:
147
+ # No Time is blank:
148
+ #
149
+ # Time.now.blank? # => false
150
+ #
151
+ # @return [false]
152
+ def blank?
153
+ false
154
+ end
155
+ end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/to_param'
2
- require 'active_support/core_ext/object/to_query'
3
- require 'active_support/core_ext/array/conversions'
4
- require 'active_support/core_ext/hash/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/to_param"
4
+ require "active_support/core_ext/object/to_query"
5
+ require "active_support/core_ext/array/conversions"
6
+ require "active_support/core_ext/hash/conversions"
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/duplicable'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
2
4
 
3
5
  class Object
4
6
  # Returns a deep copy of object if it's duplicable. If it's
@@ -25,7 +27,7 @@ class Array
25
27
  # array[1][2] # => nil
26
28
  # dup[1][2] # => 4
27
29
  def deep_dup
28
- map { |it| it.deep_dup }
30
+ map(&:deep_dup)
29
31
  end
30
32
  end
31
33
 
@@ -39,8 +41,15 @@ class Hash
39
41
  # hash[:a][:c] # => nil
40
42
  # dup[:a][:c] # => "c"
41
43
  def deep_dup
42
- each_with_object(dup) do |(key, value), hash|
43
- hash[key.deep_dup] = value.deep_dup
44
+ hash = dup
45
+ each_pair do |key, value|
46
+ if key.frozen? && ::String === key
47
+ hash[key] = value.deep_dup
48
+ else
49
+ hash.delete(key)
50
+ hash[key.deep_dup] = value.deep_dup
51
+ end
44
52
  end
53
+ hash
45
54
  end
46
55
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
4
  # Most objects are cloneable, but not all. For example you can't dup methods:
3
5
  #
@@ -19,105 +21,13 @@
19
21
  class Object
20
22
  # Can you safely dup this object?
21
23
  #
22
- # False for +nil+, +false+, +true+, symbol, number and BigDecimal(in 1.9.x) objects;
24
+ # False for method objects;
23
25
  # true otherwise.
24
26
  def duplicable?
25
27
  true
26
28
  end
27
29
  end
28
30
 
29
- class NilClass
30
- begin
31
- nil.dup
32
- rescue TypeError
33
-
34
- # +nil+ is not duplicable:
35
- #
36
- # nil.duplicable? # => false
37
- # nil.dup # => TypeError: can't dup NilClass
38
- def duplicable?
39
- false
40
- end
41
- end
42
- end
43
-
44
- class FalseClass
45
- begin
46
- false.dup
47
- rescue TypeError
48
-
49
- # +false+ is not duplicable:
50
- #
51
- # false.duplicable? # => false
52
- # false.dup # => TypeError: can't dup FalseClass
53
- def duplicable?
54
- false
55
- end
56
- end
57
- end
58
-
59
- class TrueClass
60
- begin
61
- true.dup
62
- rescue TypeError
63
-
64
- # +true+ is not duplicable:
65
- #
66
- # true.duplicable? # => false
67
- # true.dup # => TypeError: can't dup TrueClass
68
- def duplicable?
69
- false
70
- end
71
- end
72
- end
73
-
74
- class Symbol
75
- begin
76
- :symbol.dup # Ruby 2.4.x.
77
- 'symbol_from_string'.to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
78
- rescue TypeError
79
-
80
- # Symbols are not duplicable:
81
- #
82
- # :my_symbol.duplicable? # => false
83
- # :my_symbol.dup # => TypeError: can't dup Symbol
84
- def duplicable?
85
- false
86
- end
87
- end
88
- end
89
-
90
- class Numeric
91
- begin
92
- 1.dup
93
- rescue TypeError
94
-
95
- # Numbers are not duplicable:
96
- #
97
- # 3.duplicable? # => false
98
- # 3.dup # => TypeError: can't dup Integer
99
- def duplicable?
100
- false
101
- end
102
- end
103
- end
104
-
105
- require 'bigdecimal'
106
- class BigDecimal
107
- # Needed to support Ruby 1.9.x, as it doesn't allow dup on BigDecimal, instead
108
- # raises TypeError exception. Checking here on the runtime whether BigDecimal
109
- # will allow dup or not.
110
- begin
111
- BigDecimal.new('4.56').dup
112
-
113
- def duplicable?
114
- true
115
- end
116
- rescue TypeError
117
- # can't dup, so use superclass implementation
118
- end
119
- end
120
-
121
31
  class Method
122
32
  # Methods are not duplicable:
123
33
  #
@@ -127,3 +37,13 @@ class Method
127
37
  false
128
38
  end
129
39
  end
40
+
41
+ class UnboundMethod
42
+ # Unbound methods are not duplicable:
43
+ #
44
+ # method(:puts).unbind.duplicable? # => false
45
+ # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
46
+ def duplicable?
47
+ false
48
+ end
49
+ end