activesupport 5.0.0 → 6.1.0

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