activesupport 5.2.8.1 → 6.1.6.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +426 -424
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/array_inquirer.rb +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +29 -3
  8. data/lib/active_support/benchmarkable.rb +1 -1
  9. data/lib/active_support/cache/file_store.rb +34 -34
  10. data/lib/active_support/cache/mem_cache_store.rb +39 -24
  11. data/lib/active_support/cache/memory_store.rb +59 -33
  12. data/lib/active_support/cache/null_store.rb +8 -3
  13. data/lib/active_support/cache/redis_cache_store.rb +72 -45
  14. data/lib/active_support/cache/strategy/local_cache.rb +41 -26
  15. data/lib/active_support/cache.rb +148 -78
  16. data/lib/active_support/callbacks.rb +81 -64
  17. data/lib/active_support/concern.rb +70 -3
  18. data/lib/active_support/concurrency/share_lock.rb +0 -1
  19. data/lib/active_support/configurable.rb +10 -14
  20. data/lib/active_support/configuration_file.rb +51 -0
  21. data/lib/active_support/core_ext/array/access.rb +18 -6
  22. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  23. data/lib/active_support/core_ext/array/extract.rb +21 -0
  24. data/lib/active_support/core_ext/array.rb +1 -1
  25. data/lib/active_support/core_ext/benchmark.rb +2 -2
  26. data/lib/active_support/core_ext/class/attribute.rb +32 -47
  27. data/lib/active_support/core_ext/class/subclasses.rb +17 -38
  28. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  29. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  30. data/lib/active_support/core_ext/date_and_time/calculations.rb +37 -47
  31. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  32. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  33. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  34. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  35. data/lib/active_support/core_ext/digest/uuid.rb +1 -0
  36. data/lib/active_support/core_ext/enumerable.rb +171 -75
  37. data/lib/active_support/core_ext/hash/conversions.rb +3 -3
  38. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  39. data/lib/active_support/core_ext/hash/except.rb +2 -2
  40. data/lib/active_support/core_ext/hash/keys.rb +1 -30
  41. data/lib/active_support/core_ext/hash/slice.rb +6 -27
  42. data/lib/active_support/core_ext/hash.rb +1 -2
  43. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  44. data/lib/active_support/core_ext/kernel.rb +0 -1
  45. data/lib/active_support/core_ext/load_error.rb +1 -1
  46. data/lib/active_support/core_ext/marshal.rb +2 -0
  47. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  48. data/lib/active_support/core_ext/module/attribute_accessors.rb +30 -39
  49. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +17 -19
  50. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  51. data/lib/active_support/core_ext/module/delegation.rb +76 -33
  52. data/lib/active_support/core_ext/module/introspection.rb +16 -15
  53. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  54. data/lib/active_support/core_ext/module.rb +0 -1
  55. data/lib/active_support/core_ext/name_error.rb +29 -2
  56. data/lib/active_support/core_ext/numeric/conversions.rb +129 -129
  57. data/lib/active_support/core_ext/numeric.rb +0 -1
  58. data/lib/active_support/core_ext/object/blank.rb +1 -2
  59. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  60. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  61. data/lib/active_support/core_ext/object/json.rb +14 -2
  62. data/lib/active_support/core_ext/object/try.rb +17 -7
  63. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  64. data/lib/active_support/core_ext/range/compare_range.rb +34 -13
  65. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  66. data/lib/active_support/core_ext/range/each.rb +0 -1
  67. data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
  68. data/lib/active_support/core_ext/regexp.rb +8 -5
  69. data/lib/active_support/core_ext/securerandom.rb +23 -3
  70. data/lib/active_support/core_ext/string/access.rb +5 -16
  71. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  72. data/lib/active_support/core_ext/string/filters.rb +42 -1
  73. data/lib/active_support/core_ext/string/inflections.rb +45 -6
  74. data/lib/active_support/core_ext/string/inquiry.rb +1 -0
  75. data/lib/active_support/core_ext/string/multibyte.rb +6 -5
  76. data/lib/active_support/core_ext/string/output_safety.rb +70 -13
  77. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  78. data/lib/active_support/core_ext/string/strip.rb +3 -1
  79. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  80. data/lib/active_support/core_ext/symbol.rb +3 -0
  81. data/lib/active_support/core_ext/time/calculations.rb +53 -3
  82. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  83. data/lib/active_support/core_ext/uri.rb +6 -1
  84. data/lib/active_support/core_ext.rb +1 -1
  85. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  86. data/lib/active_support/current_attributes.rb +16 -2
  87. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  88. data/lib/active_support/dependencies.rb +109 -34
  89. data/lib/active_support/deprecation/behaviors.rb +16 -3
  90. data/lib/active_support/deprecation/disallowed.rb +56 -0
  91. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  92. data/lib/active_support/deprecation/method_wrappers.rb +18 -23
  93. data/lib/active_support/deprecation/proxy_wrappers.rb +29 -6
  94. data/lib/active_support/deprecation/reporting.rb +50 -7
  95. data/lib/active_support/deprecation.rb +6 -1
  96. data/lib/active_support/descendants_tracker.rb +59 -9
  97. data/lib/active_support/digest.rb +2 -0
  98. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  99. data/lib/active_support/duration/iso8601_serializer.rb +18 -14
  100. data/lib/active_support/duration.rb +82 -33
  101. data/lib/active_support/encrypted_configuration.rb +0 -4
  102. data/lib/active_support/encrypted_file.rb +22 -4
  103. data/lib/active_support/environment_inquirer.rb +20 -0
  104. data/lib/active_support/evented_file_update_checker.rb +82 -117
  105. data/lib/active_support/execution_wrapper.rb +2 -1
  106. data/lib/active_support/file_update_checker.rb +0 -1
  107. data/lib/active_support/fork_tracker.rb +64 -0
  108. data/lib/active_support/gem_version.rb +3 -3
  109. data/lib/active_support/hash_with_indifferent_access.rb +70 -42
  110. data/lib/active_support/i18n.rb +1 -0
  111. data/lib/active_support/i18n_railtie.rb +15 -8
  112. data/lib/active_support/inflector/inflections.rb +2 -7
  113. data/lib/active_support/inflector/methods.rb +49 -58
  114. data/lib/active_support/inflector/transliterate.rb +47 -18
  115. data/lib/active_support/json/decoding.rb +25 -26
  116. data/lib/active_support/json/encoding.rb +11 -3
  117. data/lib/active_support/key_generator.rb +1 -33
  118. data/lib/active_support/lazy_load_hooks.rb +5 -2
  119. data/lib/active_support/locale/en.rb +33 -0
  120. data/lib/active_support/locale/en.yml +7 -3
  121. data/lib/active_support/log_subscriber.rb +39 -9
  122. data/lib/active_support/logger.rb +2 -17
  123. data/lib/active_support/logger_silence.rb +11 -19
  124. data/lib/active_support/logger_thread_safe_level.rb +50 -6
  125. data/lib/active_support/message_encryptor.rb +8 -13
  126. data/lib/active_support/message_verifier.rb +10 -10
  127. data/lib/active_support/messages/metadata.rb +11 -2
  128. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  129. data/lib/active_support/messages/rotator.rb +10 -9
  130. data/lib/active_support/multibyte/chars.rb +10 -68
  131. data/lib/active_support/multibyte/unicode.rb +15 -327
  132. data/lib/active_support/notifications/fanout.rb +116 -16
  133. data/lib/active_support/notifications/instrumenter.rb +71 -9
  134. data/lib/active_support/notifications.rb +72 -8
  135. data/lib/active_support/number_helper/number_converter.rb +5 -6
  136. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
  137. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  138. data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
  139. data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -3
  140. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  141. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  142. data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
  143. data/lib/active_support/number_helper/rounding_helper.rb +12 -28
  144. data/lib/active_support/number_helper.rb +38 -12
  145. data/lib/active_support/option_merger.rb +22 -3
  146. data/lib/active_support/ordered_hash.rb +1 -1
  147. data/lib/active_support/ordered_options.rb +13 -3
  148. data/lib/active_support/parameter_filter.rb +133 -0
  149. data/lib/active_support/per_thread_registry.rb +2 -1
  150. data/lib/active_support/rails.rb +1 -10
  151. data/lib/active_support/railtie.rb +23 -1
  152. data/lib/active_support/reloader.rb +4 -5
  153. data/lib/active_support/rescuable.rb +4 -4
  154. data/lib/active_support/secure_compare_rotator.rb +51 -0
  155. data/lib/active_support/security_utils.rb +19 -12
  156. data/lib/active_support/string_inquirer.rb +4 -3
  157. data/lib/active_support/subscriber.rb +72 -28
  158. data/lib/active_support/tagged_logging.rb +42 -8
  159. data/lib/active_support/test_case.rb +91 -0
  160. data/lib/active_support/testing/assertions.rb +30 -9
  161. data/lib/active_support/testing/deprecation.rb +0 -1
  162. data/lib/active_support/testing/file_fixtures.rb +2 -0
  163. data/lib/active_support/testing/isolation.rb +2 -2
  164. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  165. data/lib/active_support/testing/parallelization/server.rb +78 -0
  166. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  167. data/lib/active_support/testing/parallelization.rb +51 -0
  168. data/lib/active_support/testing/stream.rb +1 -2
  169. data/lib/active_support/testing/time_helpers.rb +47 -12
  170. data/lib/active_support/time_with_zone.rb +81 -47
  171. data/lib/active_support/values/time_zone.rb +34 -17
  172. data/lib/active_support/xml_mini/jdom.rb +2 -3
  173. data/lib/active_support/xml_mini/libxml.rb +2 -2
  174. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  175. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  176. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  177. data/lib/active_support/xml_mini/rexml.rb +10 -3
  178. data/lib/active_support/xml_mini.rb +2 -10
  179. data/lib/active_support.rb +14 -1
  180. metadata +54 -27
  181. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
  182. data/lib/active_support/core_ext/hash/compact.rb +0 -29
  183. data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
  184. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  185. data/lib/active_support/core_ext/module/reachable.rb +0 -11
  186. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
  187. data/lib/active_support/core_ext/range/include_range.rb +0 -3
  188. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -2,139 +2,139 @@
2
2
 
3
3
  require "active_support/core_ext/big_decimal/conversions"
4
4
  require "active_support/number_helper"
5
- require "active_support/core_ext/module/deprecation"
6
5
 
7
- module ActiveSupport::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, locale: :fr) # => "1 234 567 890,51 €"
33
- # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
34
- # # => "($1,234,567,890.50)"
35
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
36
- # # => "£1234567890,50"
37
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
38
- # # => "1234567890,50 £"
39
- #
40
- # Percentage:
41
- # 100.to_s(:percentage) # => "100.000%"
42
- # 100.to_s(:percentage, precision: 0) # => "100%"
43
- # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
44
- # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
45
- # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
46
- # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
47
- #
48
- # Delimited:
49
- # 12345678.to_s(:delimited) # => "12,345,678"
50
- # 12345678.05.to_s(:delimited) # => "12,345,678.05"
51
- # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
52
- # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
53
- # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
54
- # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
55
- # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
56
- # # => "98 765 432,98"
57
- #
58
- # Rounded:
59
- # 111.2345.to_s(:rounded) # => "111.235"
60
- # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
61
- # 13.to_s(:rounded, precision: 5) # => "13.00000"
62
- # 389.32314.to_s(:rounded, precision: 0) # => "389"
63
- # 111.2345.to_s(:rounded, significant: true) # => "111"
64
- # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
65
- # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
66
- # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
67
- # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
68
- # # => "13"
69
- # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
70
- # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
71
- # # => "1.111,23"
72
- #
73
- # Human-friendly size in Bytes:
74
- # 123.to_s(:human_size) # => "123 Bytes"
75
- # 1234.to_s(:human_size) # => "1.21 KB"
76
- # 12345.to_s(:human_size) # => "12.1 KB"
77
- # 1234567.to_s(:human_size) # => "1.18 MB"
78
- # 1234567890.to_s(:human_size) # => "1.15 GB"
79
- # 1234567890123.to_s(:human_size) # => "1.12 TB"
80
- # 1234567890123456.to_s(:human_size) # => "1.1 PB"
81
- # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
82
- # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
83
- # 483989.to_s(:human_size, precision: 2) # => "470 KB"
84
- # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
85
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
86
- # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
87
- #
88
- # Human-friendly format:
89
- # 123.to_s(:human) # => "123"
90
- # 1234.to_s(:human) # => "1.23 Thousand"
91
- # 12345.to_s(:human) # => "12.3 Thousand"
92
- # 1234567.to_s(:human) # => "1.23 Million"
93
- # 1234567890.to_s(:human) # => "1.23 Billion"
94
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
95
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
96
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
97
- # 489939.to_s(:human, precision: 2) # => "490 Thousand"
98
- # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
99
- # 1234567.to_s(:human, precision: 4,
100
- # significant: false) # => "1.2346 Million"
101
- # 1234567.to_s(:human, precision: 1,
102
- # separator: ',',
103
- # significant: false) # => "1,2 Million"
104
- def to_s(format = nil, options = nil)
105
- case format
106
- when nil
107
- super()
108
- when Integer, String
109
- super(format)
110
- when :phone
111
- ActiveSupport::NumberHelper.number_to_phone(self, options || {})
112
- when :currency
113
- ActiveSupport::NumberHelper.number_to_currency(self, options || {})
114
- when :percentage
115
- ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
116
- when :delimited
117
- ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
118
- when :rounded
119
- ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
120
- when :human
121
- ActiveSupport::NumberHelper.number_to_human(self, options || {})
122
- when :human_size
123
- ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
124
- when Symbol
125
- super()
126
- else
127
- super(format)
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
130
+ super()
131
+ else
132
+ super(format)
133
+ end
128
134
  end
129
135
  end
130
136
  end
131
137
 
132
- # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
133
- if 0.class == Integer
134
- Integer.prepend ActiveSupport::NumericWithFormat
135
- else
136
- Fixnum.prepend ActiveSupport::NumericWithFormat
137
- Bignum.prepend ActiveSupport::NumericWithFormat
138
- end
138
+ Integer.prepend ActiveSupport::NumericWithFormat
139
139
  Float.prepend ActiveSupport::NumericWithFormat
140
140
  BigDecimal.prepend ActiveSupport::NumericWithFormat
@@ -2,5 +2,4 @@
2
2
 
3
3
  require "active_support/core_ext/numeric/bytes"
4
4
  require "active_support/core_ext/numeric/time"
5
- require "active_support/core_ext/numeric/inquiry"
6
5
  require "active_support/core_ext/numeric/conversions"
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/regexp"
4
3
  require "concurrent/map"
5
4
 
6
5
  class Object
7
6
  # An object is blank if it's false, empty, or a whitespace string.
8
- # For example, +false+, '', ' ', +nil+, [], and {} are all blank.
7
+ # For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
9
8
  #
10
9
  # This simplifies
11
10
  #
@@ -43,7 +43,7 @@ class Hash
43
43
  def deep_dup
44
44
  hash = dup
45
45
  each_pair do |key, value|
46
- if key.frozen? && ::String === key
46
+ if (::String === key && key.frozen?) || ::Symbol === key
47
47
  hash[key] = value.deep_dup
48
48
  else
49
49
  hash.delete(key)
@@ -28,93 +28,6 @@ class Object
28
28
  end
29
29
  end
30
30
 
31
- class NilClass
32
- begin
33
- nil.dup
34
- rescue TypeError
35
-
36
- # +nil+ is not duplicable:
37
- #
38
- # nil.duplicable? # => false
39
- # nil.dup # => TypeError: can't dup NilClass
40
- def duplicable?
41
- false
42
- end
43
- end
44
- end
45
-
46
- class FalseClass
47
- begin
48
- false.dup
49
- rescue TypeError
50
-
51
- # +false+ is not duplicable:
52
- #
53
- # false.duplicable? # => false
54
- # false.dup # => TypeError: can't dup FalseClass
55
- def duplicable?
56
- false
57
- end
58
- end
59
- end
60
-
61
- class TrueClass
62
- begin
63
- true.dup
64
- rescue TypeError
65
-
66
- # +true+ is not duplicable:
67
- #
68
- # true.duplicable? # => false
69
- # true.dup # => TypeError: can't dup TrueClass
70
- def duplicable?
71
- false
72
- end
73
- end
74
- end
75
-
76
- class Symbol
77
- begin
78
- :symbol.dup # Ruby 2.4.x.
79
- "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
80
- rescue TypeError
81
-
82
- # Symbols are not duplicable:
83
- #
84
- # :my_symbol.duplicable? # => false
85
- # :my_symbol.dup # => TypeError: can't dup Symbol
86
- def duplicable?
87
- false
88
- end
89
- end
90
- end
91
-
92
- class Numeric
93
- begin
94
- 1.dup
95
- rescue TypeError
96
-
97
- # Numbers are not duplicable:
98
- #
99
- # 3.duplicable? # => false
100
- # 3.dup # => TypeError: can't dup Integer
101
- def duplicable?
102
- false
103
- end
104
- end
105
- end
106
-
107
- require "bigdecimal"
108
- class BigDecimal
109
- # BigDecimals are duplicable:
110
- #
111
- # BigDecimal("1.2").duplicable? # => true
112
- # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
113
- def duplicable?
114
- true
115
- end
116
- end
117
-
118
31
  class Method
119
32
  # Methods are not duplicable:
120
33
  #
@@ -125,32 +38,12 @@ class Method
125
38
  end
126
39
  end
127
40
 
128
- class Complex
129
- begin
130
- Complex(1).dup
131
- rescue TypeError
132
-
133
- # Complexes are not duplicable:
134
- #
135
- # Complex(1).duplicable? # => false
136
- # Complex(1).dup # => TypeError: can't copy Complex
137
- def duplicable?
138
- false
139
- end
140
- end
141
- end
142
-
143
- class Rational
144
- begin
145
- Rational(1).dup
146
- rescue TypeError
147
-
148
- # Rationals are not duplicable:
149
- #
150
- # Rational(1).duplicable? # => false
151
- # Rational(1).dup # => TypeError: can't copy Rational
152
- def duplicable?
153
- false
154
- end
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
155
48
  end
156
49
  end
@@ -3,6 +3,7 @@
3
3
  # Hack to load json gem first so we can overwrite its to_json.
4
4
  require "json"
5
5
  require "bigdecimal"
6
+ require "ipaddr"
6
7
  require "uri/generic"
7
8
  require "pathname"
8
9
  require "active_support/core_ext/big_decimal/conversions" # for #to_s
@@ -14,6 +15,7 @@ require "active_support/core_ext/time/conversions"
14
15
  require "active_support/core_ext/date_time/conversions"
15
16
  require "active_support/core_ext/date/conversions"
16
17
 
18
+ #--
17
19
  # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
18
20
  # their default behavior. That said, we need to define the basic to_json method in all of them,
19
21
  # otherwise they will always use to_json gem implementation, which is backwards incompatible in
@@ -44,7 +46,7 @@ module ActiveSupport
44
46
  end
45
47
  end
46
48
 
47
- [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
49
+ [Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
48
50
  klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
49
51
  end
50
52
 
@@ -168,7 +170,11 @@ class Hash
168
170
  self
169
171
  end
170
172
 
171
- Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }]
173
+ result = {}
174
+ subset.each do |k, v|
175
+ result[k.to_s] = options ? v.as_json(options.dup) : v.as_json
176
+ end
177
+ result
172
178
  end
173
179
  end
174
180
 
@@ -214,6 +220,12 @@ class Pathname #:nodoc:
214
220
  end
215
221
  end
216
222
 
223
+ class IPAddr # :nodoc:
224
+ def as_json(options = nil)
225
+ to_s
226
+ end
227
+ end
228
+
217
229
  class Process::Status #:nodoc:
218
230
  def as_json(options = nil)
219
231
  { exitstatus: exitstatus, pid: pid }
@@ -4,21 +4,31 @@ require "delegate"
4
4
 
5
5
  module ActiveSupport
6
6
  module Tryable #:nodoc:
7
- def try(*a, &b)
8
- try!(*a, &b) if a.empty? || respond_to?(a.first)
7
+ def try(method_name = nil, *args, &b)
8
+ if method_name.nil? && block_given?
9
+ if b.arity == 0
10
+ instance_eval(&b)
11
+ else
12
+ yield self
13
+ end
14
+ elsif respond_to?(method_name)
15
+ public_send(method_name, *args, &b)
16
+ end
9
17
  end
18
+ ruby2_keywords(:try) if respond_to?(:ruby2_keywords, true)
10
19
 
11
- def try!(*a, &b)
12
- if a.empty? && block_given?
20
+ def try!(method_name = nil, *args, &b)
21
+ if method_name.nil? && block_given?
13
22
  if b.arity == 0
14
23
  instance_eval(&b)
15
24
  else
16
25
  yield self
17
26
  end
18
27
  else
19
- public_send(*a, &b)
28
+ public_send(method_name, *args, &b)
20
29
  end
21
30
  end
31
+ ruby2_keywords(:try!) if respond_to?(:ruby2_keywords, true)
22
32
  end
23
33
  end
24
34
 
@@ -135,14 +145,14 @@ class NilClass
135
145
  #
136
146
  # With +try+
137
147
  # @person.try(:children).try(:first).try(:name)
138
- def try(*args)
148
+ def try(_method_name = nil, *)
139
149
  nil
140
150
  end
141
151
 
142
152
  # Calling +try!+ on +nil+ always returns +nil+.
143
153
  #
144
154
  # nil.try!(:name) # => nil
145
- def try!(*args)
155
+ def try!(_method_name = nil, *)
146
156
  nil
147
157
  end
148
158
  end
@@ -68,7 +68,7 @@ class Object
68
68
  # You can access these methods using the class name instead:
69
69
  #
70
70
  # class Phone < ActiveRecord::Base
71
- # enum phone_number_type: [home: 0, office: 1, mobile: 2]
71
+ # enum phone_number_type: { home: 0, office: 1, mobile: 2 }
72
72
  #
73
73
  # with_options presence: true do
74
74
  # validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
@@ -1,56 +1,77 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- module CompareWithRange #:nodoc:
4
+ module CompareWithRange
5
5
  # Extends the default Range#=== to support range comparisons.
6
- # (1..5) === (1..5) # => true
7
- # (1..5) === (2..3) # => true
8
- # (1..5) === (2..6) # => false
6
+ # (1..5) === (1..5) # => true
7
+ # (1..5) === (2..3) # => true
8
+ # (1..5) === (1...6) # => true
9
+ # (1..5) === (2..6) # => false
9
10
  #
10
11
  # The native Range#=== behavior is untouched.
11
12
  # ('a'..'f') === ('c') # => true
12
13
  # (5..9) === (11) # => false
14
+ #
15
+ # The given range must be fully bounded, with both start and end.
13
16
  def ===(value)
14
17
  if value.is_a?(::Range)
18
+ is_backwards_op = value.exclude_end? ? :>= : :>
19
+ return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
15
20
  # 1...10 includes 1..9 but it does not include 1..10.
21
+ # 1..10 includes 1...11 but it does not include 1...12.
16
22
  operator = exclude_end? && !value.exclude_end? ? :< : :<=
17
- super(value.first) && value.last.send(operator, last)
23
+ value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
24
+ super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
18
25
  else
19
26
  super
20
27
  end
21
28
  end
22
29
 
23
30
  # Extends the default Range#include? to support range comparisons.
24
- # (1..5).include?(1..5) # => true
25
- # (1..5).include?(2..3) # => true
26
- # (1..5).include?(2..6) # => false
31
+ # (1..5).include?(1..5) # => true
32
+ # (1..5).include?(2..3) # => true
33
+ # (1..5).include?(1...6) # => true
34
+ # (1..5).include?(2..6) # => false
27
35
  #
28
36
  # The native Range#include? behavior is untouched.
29
37
  # ('a'..'f').include?('c') # => true
30
38
  # (5..9).include?(11) # => false
39
+ #
40
+ # The given range must be fully bounded, with both start and end.
31
41
  def include?(value)
32
42
  if value.is_a?(::Range)
43
+ is_backwards_op = value.exclude_end? ? :>= : :>
44
+ return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
33
45
  # 1...10 includes 1..9 but it does not include 1..10.
46
+ # 1..10 includes 1...11 but it does not include 1...12.
34
47
  operator = exclude_end? && !value.exclude_end? ? :< : :<=
35
- super(value.first) && value.last.send(operator, last)
48
+ value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
49
+ super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
36
50
  else
37
51
  super
38
52
  end
39
53
  end
40
54
 
41
55
  # Extends the default Range#cover? to support range comparisons.
42
- # (1..5).cover?(1..5) # => true
43
- # (1..5).cover?(2..3) # => true
44
- # (1..5).cover?(2..6) # => false
56
+ # (1..5).cover?(1..5) # => true
57
+ # (1..5).cover?(2..3) # => true
58
+ # (1..5).cover?(1...6) # => true
59
+ # (1..5).cover?(2..6) # => false
45
60
  #
46
61
  # The native Range#cover? behavior is untouched.
47
62
  # ('a'..'f').cover?('c') # => true
48
63
  # (5..9).cover?(11) # => false
64
+ #
65
+ # The given range must be fully bounded, with both start and end.
49
66
  def cover?(value)
50
67
  if value.is_a?(::Range)
68
+ is_backwards_op = value.exclude_end? ? :>= : :>
69
+ return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
51
70
  # 1...10 covers 1..9 but it does not cover 1..10.
71
+ # 1..10 covers 1...11 but it does not cover 1...12.
52
72
  operator = exclude_end? && !value.exclude_end? ? :< : :<=
53
- super(value.first) && value.last.send(operator, last)
73
+ value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
74
+ super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
54
75
  else
55
76
  super
56
77
  end