activesupport 6.0.3.4 → 6.1.2

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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +367 -454
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support.rb +13 -1
  6. data/lib/active_support/array_inquirer.rb +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +3 -3
  8. data/lib/active_support/benchmarkable.rb +1 -1
  9. data/lib/active_support/cache.rb +85 -44
  10. data/lib/active_support/cache/file_store.rb +4 -3
  11. data/lib/active_support/cache/mem_cache_store.rb +29 -18
  12. data/lib/active_support/cache/memory_store.rb +46 -26
  13. data/lib/active_support/cache/redis_cache_store.rb +27 -27
  14. data/lib/active_support/cache/strategy/local_cache.rb +21 -6
  15. data/lib/active_support/callbacks.rb +65 -56
  16. data/lib/active_support/concern.rb +46 -2
  17. data/lib/active_support/configurable.rb +3 -3
  18. data/lib/active_support/configuration_file.rb +46 -0
  19. data/lib/active_support/core_ext.rb +1 -1
  20. data/lib/active_support/core_ext/benchmark.rb +2 -2
  21. data/lib/active_support/core_ext/class/attribute.rb +34 -44
  22. data/lib/active_support/core_ext/class/subclasses.rb +17 -38
  23. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  24. data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
  25. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  26. data/lib/active_support/core_ext/enumerable.rb +76 -4
  27. data/lib/active_support/core_ext/hash/conversions.rb +2 -2
  28. data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
  29. data/lib/active_support/core_ext/hash/except.rb +1 -1
  30. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  31. data/lib/active_support/core_ext/hash/slice.rb +3 -2
  32. data/lib/active_support/core_ext/load_error.rb +1 -1
  33. data/lib/active_support/core_ext/marshal.rb +2 -0
  34. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  35. data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
  36. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
  37. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  38. data/lib/active_support/core_ext/module/delegation.rb +38 -28
  39. data/lib/active_support/core_ext/module/introspection.rb +1 -25
  40. data/lib/active_support/core_ext/name_error.rb +29 -2
  41. data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
  42. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  43. data/lib/active_support/core_ext/object/json.rb +13 -2
  44. data/lib/active_support/core_ext/object/try.rb +2 -2
  45. data/lib/active_support/core_ext/range/compare_range.rb +9 -3
  46. data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
  47. data/lib/active_support/core_ext/regexp.rb +8 -1
  48. data/lib/active_support/core_ext/string/access.rb +5 -24
  49. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  50. data/lib/active_support/core_ext/string/inflections.rb +38 -4
  51. data/lib/active_support/core_ext/string/inquiry.rb +1 -0
  52. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  53. data/lib/active_support/core_ext/string/output_safety.rb +10 -10
  54. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  55. data/lib/active_support/core_ext/symbol.rb +3 -0
  56. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  57. data/lib/active_support/core_ext/time/calculations.rb +27 -3
  58. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  59. data/lib/active_support/core_ext/uri.rb +5 -1
  60. data/lib/active_support/current_attributes.rb +7 -2
  61. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  62. data/lib/active_support/dependencies.rb +43 -19
  63. data/lib/active_support/deprecation.rb +6 -1
  64. data/lib/active_support/deprecation/behaviors.rb +15 -2
  65. data/lib/active_support/deprecation/disallowed.rb +56 -0
  66. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  67. data/lib/active_support/deprecation/method_wrappers.rb +3 -2
  68. data/lib/active_support/deprecation/proxy_wrappers.rb +3 -3
  69. data/lib/active_support/deprecation/reporting.rb +50 -7
  70. data/lib/active_support/descendants_tracker.rb +6 -2
  71. data/lib/active_support/duration.rb +71 -22
  72. data/lib/active_support/duration/iso8601_serializer.rb +15 -9
  73. data/lib/active_support/encrypted_file.rb +19 -2
  74. data/lib/active_support/environment_inquirer.rb +20 -0
  75. data/lib/active_support/evented_file_update_checker.rb +69 -133
  76. data/lib/active_support/fork_tracker.rb +62 -0
  77. data/lib/active_support/gem_version.rb +3 -3
  78. data/lib/active_support/hash_with_indifferent_access.rb +42 -23
  79. data/lib/active_support/i18n_railtie.rb +14 -19
  80. data/lib/active_support/inflector/inflections.rb +1 -2
  81. data/lib/active_support/inflector/methods.rb +35 -31
  82. data/lib/active_support/inflector/transliterate.rb +4 -4
  83. data/lib/active_support/json/decoding.rb +4 -4
  84. data/lib/active_support/json/encoding.rb +5 -1
  85. data/lib/active_support/key_generator.rb +1 -1
  86. data/lib/active_support/locale/en.yml +7 -3
  87. data/lib/active_support/log_subscriber.rb +8 -0
  88. data/lib/active_support/logger.rb +1 -1
  89. data/lib/active_support/logger_silence.rb +2 -26
  90. data/lib/active_support/logger_thread_safe_level.rb +34 -12
  91. data/lib/active_support/message_encryptor.rb +4 -7
  92. data/lib/active_support/message_verifier.rb +5 -5
  93. data/lib/active_support/messages/metadata.rb +9 -1
  94. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  95. data/lib/active_support/messages/rotator.rb +6 -5
  96. data/lib/active_support/multibyte/chars.rb +4 -42
  97. data/lib/active_support/multibyte/unicode.rb +9 -83
  98. data/lib/active_support/notifications.rb +31 -4
  99. data/lib/active_support/notifications/fanout.rb +23 -8
  100. data/lib/active_support/notifications/instrumenter.rb +6 -15
  101. data/lib/active_support/number_helper.rb +29 -14
  102. data/lib/active_support/number_helper/number_converter.rb +1 -1
  103. data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -7
  104. data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
  105. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  106. data/lib/active_support/number_helper/number_to_rounded_converter.rb +3 -3
  107. data/lib/active_support/number_helper/rounding_helper.rb +12 -28
  108. data/lib/active_support/option_merger.rb +3 -2
  109. data/lib/active_support/ordered_options.rb +8 -2
  110. data/lib/active_support/parameter_filter.rb +15 -10
  111. data/lib/active_support/per_thread_registry.rb +1 -1
  112. data/lib/active_support/rails.rb +1 -4
  113. data/lib/active_support/railtie.rb +23 -1
  114. data/lib/active_support/rescuable.rb +4 -4
  115. data/lib/active_support/secure_compare_rotator.rb +51 -0
  116. data/lib/active_support/security_utils.rb +19 -12
  117. data/lib/active_support/string_inquirer.rb +4 -2
  118. data/lib/active_support/subscriber.rb +12 -7
  119. data/lib/active_support/tagged_logging.rb +29 -4
  120. data/lib/active_support/testing/assertions.rb +18 -11
  121. data/lib/active_support/testing/parallelization.rb +12 -95
  122. data/lib/active_support/testing/parallelization/server.rb +78 -0
  123. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  124. data/lib/active_support/testing/time_helpers.rb +40 -3
  125. data/lib/active_support/time_with_zone.rb +66 -42
  126. data/lib/active_support/values/time_zone.rb +20 -10
  127. data/lib/active_support/xml_mini/rexml.rb +8 -1
  128. metadata +34 -36
  129. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
  130. data/lib/active_support/core_ext/hash/compact.rb +0 -5
  131. data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
  132. data/lib/active_support/core_ext/module/reachable.rb +0 -6
  133. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
  134. data/lib/active_support/core_ext/range/include_range.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff7b5b5d2d8e4e8ef3da05784a2431358d974c2065d6a26e06d588070af9b7b7
4
- data.tar.gz: 12ce4b243164ad07b27f631332a7616eceda9f64db3caf5756bb20aad0213815
3
+ metadata.gz: 6326314394101143f281211cb89d1042e569d7426be263d1f8e69c596ccf366a
4
+ data.tar.gz: 36b3d5e51a648b00293158f83101d18d5783a67c315c90532692543645438b25
5
5
  SHA512:
6
- metadata.gz: 5d0bda6afe7b4ee9173289cb3d641e2ebfb61f0ca6f90b97dbf22c7edb4774fad897953031ff71bc03b399d59e7cd01c9be72d50ea7fbcab891b72bf9654a83c
7
- data.tar.gz: d1c75dfb14a905e500fdc4a3b7882578133ea555ddd0d9e11f13515cfa9c1f79ea036f0b35ba26efb7958a4e639ad9226e57e370a63590ac6e18c772b509079f
6
+ metadata.gz: 37d0490abe7cb3e02522a1f4d7b73044cd2bc97767a9bff3981da6abd2ba8f426ee9d09bbabf25489c07b676dbf3ac6e31535ac72a15723bf8aaf1db3ba3f2ed
7
+ data.tar.gz: d2bc56dfb71130dbd367c93d24decc7a41c6154630755a35cca489b9246c65e19dd740d8509384a7db58f255a483c99ed8abfb22d3bec248b05328e849826eca
data/CHANGELOG.md CHANGED
@@ -1,681 +1,594 @@
1
- ## Rails 6.0.3.4 (October 07, 2020) ##
1
+ ## Rails 6.1.2 (February 09, 2021) ##
2
2
 
3
- * No changes.
3
+ * `ActiveSupport::Cache::MemCacheStore` now accepts an explicit `nil` for its `addresses` argument.
4
4
 
5
+ ```ruby
6
+ config.cache_store = :mem_cache_store, nil
5
7
 
6
- ## Rails 6.0.3.3 (September 09, 2020) ##
7
-
8
- * No changes.
8
+ # is now equivalent to
9
9
 
10
+ config.cache_store = :mem_cache_store
10
11
 
11
- ## Rails 6.0.3.2 (June 17, 2020) ##
12
+ # and is also equivalent to
12
13
 
13
- * No changes.
14
+ config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
14
15
 
16
+ # which is the fallback behavior of Dalli
17
+ ```
15
18
 
16
- ## Rails 6.0.3.1 (May 18, 2020) ##
19
+ This helps those migrating from `:dalli_store`, where an explicit `nil` was permitted.
17
20
 
18
- * [CVE-2020-8165] Deprecate Marshal.load on raw cache read in RedisCacheStore
21
+ *Michael Overmeyer*
19
22
 
20
- * [CVE-2020-8165] Avoid Marshal.load on raw cache value in MemCacheStore
21
23
 
22
- ## Rails 6.0.3 (May 06, 2020) ##
24
+ ## Rails 6.1.1 (January 07, 2021) ##
23
25
 
24
- * `Array#to_sentence` no longer returns a frozen string.
26
+ * Change `IPAddr#to_json` to match the behavior of the json gem returning the string representation
27
+ instead of the instance variables of the object.
25
28
 
26
29
  Before:
27
30
 
28
- ['one', 'two'].to_sentence.frozen?
29
- # => true
31
+ ```ruby
32
+ IPAddr.new("127.0.0.1").to_json
33
+ # => "{\"addr\":2130706433,\"family\":2,\"mask_addr\":4294967295}"
34
+ ```
30
35
 
31
36
  After:
32
37
 
33
- ['one', 'two'].to_sentence.frozen?
34
- # => false
35
-
36
- *Nicolas Dular*
37
-
38
- * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
39
- `ActiveSupport.parse_json_times = true`.
40
-
41
- *Christian Gregg*
42
-
43
-
44
- ## Rails 6.0.2.2 (March 19, 2020) ##
45
-
46
- * No changes.
47
-
48
-
49
- ## Rails 6.0.2.1 (December 18, 2019) ##
50
-
51
- * No changes.
52
-
53
-
54
- ## Rails 6.0.2 (December 13, 2019) ##
55
-
56
- * Eager load translations during initialization.
57
-
58
- *Diego Plentz*
59
-
60
- * Use per-thread CPU time clock on `ActiveSupport::Notifications`.
61
-
62
- *George Claghorn*
63
-
64
-
65
- ## Rails 6.0.1 (November 5, 2019) ##
66
-
67
- * `ActiveSupport::SafeBuffer` supports `Enumerator` methods.
68
-
69
- *Shugo Maeda*
70
-
71
- * The Redis cache store fails gracefully when the server returns a "max number
72
- of clients reached" error.
73
-
74
- *Brandon Medenwald*
75
-
76
- * Fixed that mutating a value returned by a memory cache store would
77
- unexpectedly change the cached value.
78
-
79
- *Jonathan Hyman*
80
-
81
- * The default inflectors in `zeitwerk` mode support overrides:
82
-
83
38
  ```ruby
84
- # config/initializers/zeitwerk.rb
85
- Rails.autoloaders.each do |autoloader|
86
- autoloader.inflector.inflect(
87
- "html_parser" => "HTMLParser",
88
- "ssl_error" => "SSLError"
89
- )
90
- end
39
+ IPAddr.new("127.0.0.1").to_json
40
+ # => "\"127.0.0.1\""
91
41
  ```
92
42
 
93
- That way, you can tweak how individual basenames are inflected without touching Active Support inflection rules, which are global. These inflectors fallback to `String#camelize`, so existing inflection rules are still taken into account for non-overridden basenames.
94
43
 
95
- Please, check the [autoloading guide for `zeitwerk` mode](https://guides.rubyonrails.org/v6.0/autoloading_and_reloading_constants.html#customizing-inflections) if you prefer not to depend on `String#camelize` at all.
44
+ ## Rails 6.1.0 (December 09, 2020) ##
96
45
 
97
- *Xavier Noria*
46
+ * Ensure `MemoryStore` disables compression by default. Reverts behavior of
47
+ `MemoryStore` to its prior rails `5.1` behavior.
98
48
 
99
- * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
100
- and endless range targets.
49
+ *Max Gurewitz*
101
50
 
102
- *Allen Hsu*, *Andrew Hodgkinson*
51
+ * Calling `iso8601` on negative durations retains the negative sign on individual
52
+ digits instead of prepending it.
103
53
 
104
- * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
54
+ This change is required so we can interoperate with PostgreSQL, which prefers
55
+ negative signs for each component.
105
56
 
106
- *Iain Beeston*
107
-
108
-
109
- ## Rails 6.0.0 (August 16, 2019) ##
110
-
111
- * Let `require_dependency` in `zeitwerk` mode look the autoload paths up for
112
- better backwards compatibility.
113
-
114
- *Xavier Noria*
115
-
116
- * Let `require_dependency` in `zeitwerk` mode support arguments that respond
117
- to `to_path` for better backwards compatibility.
118
-
119
- *Xavier Noria*
120
-
121
- * Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
122
-
123
- Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
124
- to make log level local to Ruby Fibers in addition to Threads.
125
-
126
- Example:
127
-
128
- logger = ActiveSupport::Logger.new(STDOUT)
129
- logger.level = 1
130
- p "Main is debug? #{logger.debug?}"
131
-
132
- Fiber.new {
133
- logger.local_level = 0
134
- p "Thread is debug? #{logger.debug?}"
135
- }.resume
136
-
137
- p "Main is debug? #{logger.debug?}"
57
+ Compatibility with other iso8601 parsers which support leading negatives as well
58
+ as negatives per component is still retained.
138
59
 
139
60
  Before:
140
61
 
141
- Main is debug? false
142
- Thread is debug? true
143
- Main is debug? true
62
+ (-1.year - 1.day).iso8601
63
+ # => "-P1Y1D"
144
64
 
145
65
  After:
146
66
 
147
- Main is debug? false
148
- Thread is debug? true
149
- Main is debug? false
67
+ (-1.year - 1.day).iso8601
68
+ # => "P-1Y-1D"
150
69
 
151
- *Alexander Varnin*
152
-
153
- * Do not delegate missing `marshal_dump` and `_dump` methods via the
154
- `delegate_missing_to` extension. This avoids unintentionally adding instance
155
- variables when calling `Marshal.dump(object)`, should the delegation target of
156
- `object` be a method which would otherwise add them. Fixes #36522.
157
-
158
- *Aaron Lipman*
159
-
160
-
161
- ## Rails 6.0.0.rc2 (July 22, 2019) ##
162
-
163
- * `truncate` would return the original string if it was too short to be truncated
164
- and a frozen string if it were long enough to be truncated. Now truncate will
165
- consistently return an unfrozen string regardless. This behavior is consistent
166
- with `gsub` and `strip`.
70
+ *Vipul A M*
167
71
 
168
- Before:
169
-
170
- 'foobar'.truncate(5).frozen?
171
- # => true
172
- 'foobar'.truncate(6).frozen?
173
- # => false
72
+ * Remove deprecated `ActiveSupport::Notifications::Instrumenter#end=`.
174
73
 
175
- After:
74
+ *Rafael Mendonça França*
176
75
 
177
- 'foobar'.truncate(5).frozen?
178
- # => false
179
- 'foobar'.truncate(6).frozen?
180
- # => false
76
+ * Deprecate `ActiveSupport::Multibyte::Unicode.default_normalization_form`.
181
77
 
182
- *Jordan Thomas*
78
+ *Rafael Mendonça França*
183
79
 
80
+ * Remove deprecated `ActiveSupport::Multibyte::Unicode.pack_graphemes`,
81
+ `ActiveSupport::Multibyte::Unicode.unpack_graphemes`,
82
+ `ActiveSupport::Multibyte::Unicode.normalize`,
83
+ `ActiveSupport::Multibyte::Unicode.downcase`,
84
+ `ActiveSupport::Multibyte::Unicode.upcase` and `ActiveSupport::Multibyte::Unicode.swapcase`.
184
85
 
185
- ## Rails 6.0.0.rc1 (April 24, 2019) ##
86
+ *Rafael Mendonça França*
186
87
 
187
- * Introduce `ActiveSupport::ActionableError`.
88
+ * Remove deprecated `ActiveSupport::Multibyte::Chars#consumes?` and `ActiveSupport::Multibyte::Chars#normalize`.
188
89
 
189
- Actionable errors let's you dispatch actions from Rails' error pages. This
190
- can help you save time if you have a clear action for the resolution of
191
- common development errors.
90
+ *Rafael Mendonça França*
192
91
 
193
- The de-facto example are pending migrations. Every time pending migrations
194
- are found, a middleware raises an error. With actionable errors, you can
195
- run the migrations right from the error page. Other examples include Rails
196
- plugins that need to run a rake task to setup themselves. They can now
197
- raise actionable errors to run the setup straight from the error pages.
92
+ * Remove deprecated file `active_support/core_ext/range/include_range`.
198
93
 
199
- Here is how to define an actionable error:
94
+ *Rafael Mendonça França*
200
95
 
201
- ```ruby
202
- class PendingMigrationError < MigrationError #:nodoc:
203
- include ActiveSupport::ActionableError
96
+ * Remove deprecated file `active_support/core_ext/hash/transform_values`.
204
97
 
205
- action "Run pending migrations" do
206
- ActiveRecord::Tasks::DatabaseTasks.migrate
207
- end
208
- end
209
- ```
98
+ *Rafael Mendonça França*
210
99
 
211
- To make an error actionable, include the `ActiveSupport::ActionableError`
212
- module and invoke the `action` class macro to define the action. An action
213
- needs a name and a procedure to execute. The name is shown as the name of a
214
- button on the error pages. Once clicked, it will invoke the given
215
- procedure.
100
+ * Remove deprecated file `active_support/core_ext/hash/compact`.
216
101
 
217
- *Vipul A M*, *Yao Jie*, *Genadi Samokovarov*
102
+ *Rafael Mendonça França*
218
103
 
219
- * Preserve `html_safe?` status on `ActiveSupport::SafeBuffer#*`.
104
+ * Remove deprecated file `active_support/core_ext/array/prepend_and_append`.
220
105
 
221
- Before:
106
+ *Rafael Mendonça França*
222
107
 
223
- ("<br />".html_safe * 2).html_safe? #=> nil
108
+ * Remove deprecated file `active_support/core_ext/numeric/inquiry`.
224
109
 
225
- After:
110
+ *Rafael Mendonça França*
226
111
 
227
- ("<br />".html_safe * 2).html_safe? #=> true
112
+ * Remove deprecated file `active_support/core_ext/module/reachable`.
228
113
 
229
- *Ryo Nakamura*
114
+ *Rafael Mendonça França*
230
115
 
231
- * Calling test methods with `with_info_handler` method to allow minitest-hooks
232
- plugin to work.
116
+ * Remove deprecated `Module#parent_name`, `Module#parent` and `Module#parents`.
233
117
 
234
- *Mauri Mustonen*
118
+ *Rafael Mendonça França*
235
119
 
236
- * The Zeitwerk compatibility interface for `ActiveSupport::Dependencies` no
237
- longer implements `autoloaded_constants` or `autoloaded?` (undocumented,
238
- anyway). Experience shows introspection does not have many use cases, and
239
- troubleshooting is done by logging. With this design trade-off we are able
240
- to use even less memory in all environments.
120
+ * Remove deprecated `ActiveSupport::LoggerThreadSafeLevel#after_initialize`.
241
121
 
242
- *Xavier Noria*
122
+ *Rafael Mendonça França*
243
123
 
244
- * Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
245
- and hence uses less memory when `config.cache_classes` is `true`, a standard
246
- setup in production.
124
+ * Remove deprecated `LoggerSilence` constant.
247
125
 
248
- *Xavier Noria*
126
+ *Rafael Mendonça França*
249
127
 
250
- * In `:zeitwerk` mode, eager load directories in engines and applications only
251
- if present in their respective `config.eager_load_paths`.
128
+ * Remove deprecated fallback to `I18n.default_local` when `config.i18n.fallbacks` is empty.
252
129
 
253
- A common use case for this is adding `lib` to `config.autoload_paths`, but
254
- not to `config.eager_load_paths`. In that configuration, for example, files
255
- in the `lib` directory should not be eager loaded.
130
+ *Rafael Mendonça França*
256
131
 
257
- *Xavier Noria*
132
+ * Remove entries from local cache on `RedisCacheStore#delete_matched`
258
133
 
259
- * Fix bug in Range comparisons when comparing to an excluded-end Range
134
+ Fixes #38627
260
135
 
261
- Before:
136
+ *ojab*
262
137
 
263
- (1..10).cover?(1...11) # => false
138
+ * Speed up `ActiveSupport::SecurityUtils.fixed_length_secure_compare` by using
139
+ `OpenSSL.fixed_length_secure_compare`, if available.
264
140
 
265
- After:
141
+ *Nate Matykiewicz*
266
142
 
267
- (1..10).cover?(1...11) # => true
143
+ * `ActiveSupport::Cache::MemCacheStore` now checks `ENV["MEMCACHE_SERVERS"]` before falling back to `"localhost:11211"` if configured without any addresses.
268
144
 
269
- With the same change for `Range#include?` and `Range#===`.
145
+ ```ruby
146
+ config.cache_store = :mem_cache_store
270
147
 
271
- *Owen Stephens*
148
+ # is now equivalent to
272
149
 
273
- * Use weak references in descendants tracker to allow anonymous subclasses to
274
- be garbage collected.
150
+ config.cache_store = :mem_cache_store, ENV["MEMCACHE_SERVERS"] || "localhost:11211"
275
151
 
276
- *Edgars Beigarts*
152
+ # instead of
277
153
 
278
- * Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
279
- passing a block optional. This will let users use
280
- `ActiveSupport::Notifications` messaging features outside of
281
- instrumentation.
154
+ config.cache_store = :mem_cache_store, "localhost:11211" # ignores ENV["MEMCACHE_SERVERS"]
155
+ ```
282
156
 
283
- *Ali Ibrahim*
157
+ *Sam Bostock*
284
158
 
285
- * Fix `Time#advance` to work with dates before 1001-03-07
159
+ * `ActiveSupport::Subscriber#attach_to` now accepts an `inherit_all:` argument. When set to true,
160
+ it allows a subscriber to receive events for methods defined in the subscriber's ancestor class(es).
286
161
 
287
- Before:
162
+ ```ruby
163
+ class ActionControllerSubscriber < ActiveSupport::Subscriber
164
+ attach_to :action_controller
288
165
 
289
- Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
166
+ def start_processing(event)
167
+ info "Processing by #{event.payload[:controller]}##{event.payload[:action]} as #{format}"
168
+ end
290
169
 
291
- After
170
+ def redirect_to(event)
171
+ info { "Redirected to #{event.payload[:location]}" }
172
+ end
173
+ end
292
174
 
293
- Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC
175
+ # We detach ActionControllerSubscriber from the :action_controller namespace so that our CustomActionControllerSubscriber
176
+ # can provide its own instrumentation for certain events in the namespace
177
+ ActionControllerSubscriber.detach_from(:action_controller)
294
178
 
295
- Note that this doesn't affect `DateTime#advance` as that doesn't use a proleptic calendar.
179
+ class CustomActionControllerSubscriber < ActionControllerSubscriber
180
+ attach_to :action_controller, inherit_all: true
296
181
 
297
- *Andrew White*
182
+ def start_processing(event)
183
+ info "A custom response to start_processing events"
184
+ end
298
185
 
299
- * In Zeitwerk mode, engines are now managed by the `main` autoloader. Engines may reference application constants, if the application is reloaded and we do not reload engines, they won't use the reloaded application code.
186
+ # => CustomActionControllerSubscriber will process events for "start_processing.action_controller" notifications
187
+ # using its own #start_processing implementation, while retaining ActionControllerSubscriber's instrumentation
188
+ # for "redirect_to.action_controller" notifications
189
+ end
190
+ ```
300
191
 
301
- *Xavier Noria*
192
+ *Adrianna Chang*
302
193
 
303
- * Add support for supplying `locale` to `transliterate` and `parameterize`.
194
+ * Allow the digest class used to generate non-sensitive digests to be configured with `config.active_support.hash_digest_class`.
304
195
 
305
- I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })
196
+ `config.active_support.use_sha1_digests` is deprecated in favour of `config.active_support.hash_digest_class = ::Digest::SHA1`.
306
197
 
307
- ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
308
- "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
309
- ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
198
+ *Dirkjan Bussink*
310
199
 
311
- *Kaan Ozkan*, *Sharang Dashputre*
200
+ * Fix bug to make memcached write_entry expire correctly with unless_exist
312
201
 
313
- * Allow `Array#excluding` and `Enumerable#excluding` to deal with a passed array gracefully.
202
+ *Jye Lee*
314
203
 
315
- [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
204
+ * Add `ActiveSupport::Duration` conversion methods
316
205
 
317
- *DHH*
206
+ `in_seconds`, `in_minutes`, `in_hours`, `in_days`, `in_weeks`, `in_months`, and `in_years` return the respective duration covered.
318
207
 
319
- * Renamed `Array#without` and `Enumerable#without` to `Array#excluding` and `Enumerable#excluding`, to create parity with
320
- `Array#including` and `Enumerable#including`. Retained the old names as aliases.
208
+ *Jason York*
321
209
 
322
- *DHH*
210
+ * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
211
+ to `read_multi` causing `fetch_multi` to not work properly
323
212
 
324
- * Added `Array#including` and `Enumerable#including` to conveniently enlarge a collection with more members using a method rather than an operator:
213
+ *Rajesh Sharma*
325
214
 
326
- [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
327
- post.authors.including(Current.person) # => All the authors plus the current person!
215
+ * Fixed issue in `ActiveSupport::Cache::MemCacheStore` which caused duplicate compression,
216
+ and caused the provided `compression_threshold` to not be respected.
328
217
 
329
- *DHH*
218
+ *Max Gurewitz*
330
219
 
220
+ * Prevent `RedisCacheStore` and `MemCacheStore` from performing compression
221
+ when reading entries written with `raw: true`.
331
222
 
332
- ## Rails 6.0.0.beta3 (March 11, 2019) ##
223
+ *Max Gurewitz*
333
224
 
334
- * No changes.
225
+ * `URI.parser` is deprecated and will be removed in Rails 6.2. Use
226
+ `URI::DEFAULT_PARSER` instead.
335
227
 
228
+ *Jean Boussier*
336
229
 
337
- ## Rails 6.0.0.beta2 (February 25, 2019) ##
230
+ * `require_dependency` has been documented to be _obsolete_ in `:zeitwerk`
231
+ mode. The method is not deprecated as such (yet), but applications are
232
+ encouraged to not use it.
338
233
 
339
- * New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).
234
+ In `:zeitwerk` mode, semantics match Ruby's and you do not need to be
235
+ defensive with load order. Just refer to classes and modules normally. If
236
+ the constant name is dynamic, camelize if needed, and constantize.
340
237
 
341
238
  *Xavier Noria*
342
239
 
343
- * Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.
240
+ * Add 3rd person aliases of `Symbol#start_with?` and `Symbol#end_with?`.
344
241
 
345
- *Zach Kemp*
346
-
347
- * Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.
348
-
349
- *Rosa Gutierrez*
350
-
351
- * Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
352
-
353
- *Akinori Musha*
354
-
355
- * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
356
-
357
- `assoc` can now be called with either a string or a symbol.
242
+ ```ruby
243
+ :foo.starts_with?("f") # => true
244
+ :foo.ends_with?("o") # => true
245
+ ```
358
246
 
359
- *Stefan Schüßler*
247
+ *Ryuta Kamizono*
360
248
 
361
- * Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.
249
+ * Add override of unary plus for `ActiveSupport::Duration`.
362
250
 
363
- *Guillermo Iguaran*
251
+ `+ 1.second` is now identical to `+1.second` to prevent errors
252
+ where a seemingly innocent change of formatting leads to a change in the code behavior.
364
253
 
254
+ Before:
255
+ ```ruby
256
+ +1.second.class
257
+ # => ActiveSupport::Duration
258
+ (+ 1.second).class
259
+ # => Integer
260
+ ```
365
261
 
366
- ## Rails 6.0.0.beta1 (January 18, 2019) ##
262
+ After:
263
+ ```ruby
264
+ +1.second.class
265
+ # => ActiveSupport::Duration
266
+ (+ 1.second).class
267
+ # => ActiveSupport::Duration
268
+ ```
367
269
 
368
- * Remove deprecated `Module#reachable?` method.
270
+ Fixes #39079.
369
271
 
370
- *Rafael Mendonça França*
272
+ *Roman Kushnir*
371
273
 
372
- * Remove deprecated `#acronym_regex` method from `Inflections`.
274
+ * Add subsec to `ActiveSupport::TimeWithZone#inspect`.
373
275
 
374
- *Rafael Mendonça França*
276
+ Before:
375
277
 
376
- * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
278
+ Time.at(1498099140).in_time_zone.inspect
279
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
280
+ Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
281
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
282
+ Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
283
+ # => "Thu, 22 Jun 2017 02:39:00 UTC +00:00"
377
284
 
378
- *Keenan Brock*
285
+ After:
379
286
 
380
- * Preserve key order passed to `ActiveSupport::CacheStore#fetch_multi`.
287
+ Time.at(1498099140).in_time_zone.inspect
288
+ # => "Thu, 22 Jun 2017 02:39:00.000000000 UTC +00:00"
289
+ Time.at(1498099140, 123456780, :nsec).in_time_zone.inspect
290
+ # => "Thu, 22 Jun 2017 02:39:00.123456780 UTC +00:00"
291
+ Time.at(1498099140 + Rational("1/3")).in_time_zone.inspect
292
+ # => "Thu, 22 Jun 2017 02:39:00.333333333 UTC +00:00"
381
293
 
382
- `fetch_multi(*names)` now returns its results in the same order as the `*names` requested, rather than returning cache hits followed by cache misses.
294
+ *akinomaeni*
383
295
 
384
- *Gannon McGibbon*
296
+ * Calling `ActiveSupport::TaggedLogging#tagged` without a block now returns a tagged logger.
385
297
 
386
- * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
298
+ ```ruby
299
+ logger.tagged("BCX").info("Funky time!") # => [BCX] Funky time!
300
+ ```
387
301
 
388
- *Mark J. Titorenko*, *Vlad Bokov*
302
+ *Eugene Kenny*
389
303
 
390
- * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
391
- would not act as alias for `#symbolize_keys`.
304
+ * Align `Range#cover?` extension behavior with Ruby behavior for backwards ranges.
392
305
 
393
- *Nick Weiland*
306
+ `(1..10).cover?(5..3)` now returns `false`, as it does in plain Ruby.
394
307
 
395
- * Improve the logic that detects non-autoloaded constants.
308
+ Also update `#include?` and `#===` behavior to match.
396
309
 
397
- *Jan Habermann*, *Xavier Noria*
310
+ *Michael Groeneman*
398
311
 
399
- * Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` and `ActiveSupport::Multibyte::Unicode#unpack_graphemes(string)`
400
- in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively.
312
+ * Update to TZInfo v2.0.0.
401
313
 
402
- *Francesco Rodríguez*
314
+ This changes the output of `ActiveSupport::TimeZone.utc_to_local`, but
315
+ can be controlled with the
316
+ `ActiveSupport.utc_to_local_returns_utc_offset_times` config.
403
317
 
404
- * Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.
318
+ New Rails 6.1 apps have it enabled by default, existing apps can upgrade
319
+ via the config in config/initializers/new_framework_defaults_6_1.rb
405
320
 
406
- *Francesco Rodríguez*
321
+ See the `utc_to_local_returns_utc_offset_times` documentation for details.
407
322
 
408
- * Fix duration being rounded to a full second.
409
- ```
410
- time = DateTime.parse("2018-1-1")
411
- time += 0.51.seconds
412
- ```
413
- Will now correctly add 0.51 second and not 1 full second.
323
+ *Phil Ross*, *Jared Beck*
414
324
 
415
- *Edouard Chin*
325
+ * Add Date and Time `#yesterday?` and `#tomorrow?` alongside `#today?`.
416
326
 
417
- * Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSupport::Multibyte::Chars#normalize`
418
- in favor of `String#unicode_normalize`
327
+ Aliased to `#prev_day?` and `#next_day?` to match the existing `#prev/next_day` methods.
419
328
 
420
- *Francesco Rodríguez*
329
+ *Jatin Dhankhar*
421
330
 
422
- * Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
423
- `String#downcase/upcase/swapcase`.
331
+ * Add `Enumerable#pick` to complement `ActiveRecord::Relation#pick`.
424
332
 
425
- *Francesco Rodríguez*
333
+ *Eugene Kenny*
426
334
 
427
- * Add `ActiveSupport::ParameterFilter`.
335
+ * [Breaking change] `ActiveSupport::Callbacks#halted_callback_hook` now receive a 2nd argument:
428
336
 
429
- *Yoshiyuki Kinjo*
337
+ `ActiveSupport::Callbacks#halted_callback_hook` now receive the name of the callback
338
+ being halted as second argument.
339
+ This change will allow you to differentiate which callbacks halted the chain
340
+ and act accordingly.
430
341
 
431
- * Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
432
- `module_parent`, `module_parents`, and `module_parent_name`.
342
+ ```ruby
343
+ class Book < ApplicationRecord
344
+ before_save { throw(:abort) }
345
+ before_create { throw(:abort) }
433
346
 
434
- *Gannon McGibbon*
347
+ def halted_callback_hook(filter, callback_name)
348
+ Rails.logger.info("Book couldn't be #{callback_name}d")
349
+ end
435
350
 
436
- * Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`
351
+ Book.create # => "Book couldn't be created"
352
+ book.save # => "Book couldn't be saved"
353
+ end
354
+ ```
437
355
 
438
356
  *Edouard Chin*
439
357
 
440
- * Deprecate using negative limits in `String#first` and `String#last`.
441
-
442
- *Gannon McGibbon*, *Eric Turner*
443
-
444
- * Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
445
- with symbol arguments
446
-
447
- *Abraham Chan*
358
+ * Support `prepend` with `ActiveSupport::Concern`.
448
359
 
449
- * Treat `#delete_prefix`, `#delete_suffix` and `#unicode_normalize` results as non-`html_safe`.
450
- Ensure safety of arguments for `#insert`, `#[]=` and `#replace` calls on `html_safe` Strings.
360
+ Allows a module with `extend ActiveSupport::Concern` to be prepended.
451
361
 
452
- *Janosch Müller*
362
+ module Imposter
363
+ extend ActiveSupport::Concern
453
364
 
454
- * Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
455
- of mutating the one received as parameter.
456
-
457
- *Thierry Joyal*
458
-
459
- * Define `unfreeze_time` as an alias of `travel_back` in `ActiveSupport::Testing::TimeHelpers`.
365
+ # Same as `included`, except only run when prepended.
366
+ prepended do
367
+ end
368
+ end
460
369
 
461
- The alias is provided for symmetry with `freeze_time`.
370
+ class Person
371
+ prepend Imposter
372
+ end
462
373
 
463
- *Ryan Davidson*
374
+ Class methods are prepended to the base class, concerning is also
375
+ updated: `concerning :Imposter, prepend: true do`.
464
376
 
465
- * Add support for tracing constant autoloads. Just throw
377
+ *Jason Karns*, *Elia Schito*
466
378
 
467
- ActiveSupport::Dependencies.logger = Rails.logger
468
- ActiveSupport::Dependencies.verbose = true
379
+ * Deprecate using `Range#include?` method to check the inclusion of a value
380
+ in a date time range. It is recommended to use `Range#cover?` method
381
+ instead of `Range#include?` to check the inclusion of a value
382
+ in a date time range.
469
383
 
470
- in an initializer.
384
+ *Vishal Telangre*
471
385
 
472
- *Xavier Noria*
386
+ * Support added for a `round_mode` parameter, in all number helpers. (See: `BigDecimal::mode`.)
473
387
 
474
- * Maintain `html_safe?` on html_safe strings when sliced.
388
+ ```ruby
389
+ number_to_currency(1234567890.50, precision: 0, round_mode: :half_down) # => "$1,234,567,890"
390
+ number_to_percentage(302.24398923423, precision: 5, round_mode: :down) # => "302.24398%"
391
+ number_to_rounded(389.32314, precision: 0, round_mode: :ceil) # => "390"
392
+ number_to_human_size(483989, precision: 2, round_mode: :up) # => "480 KB"
393
+ number_to_human(489939, precision: 2, round_mode: :floor) # => "480 Thousand"
475
394
 
476
- string = "<div>test</div>".html_safe
477
- string[-1..1].html_safe? # => true
395
+ 485000.to_s(:human, precision: 2, round_mode: :half_even) # => "480 Thousand"
396
+ ```
478
397
 
479
- *Elom Gomez*, *Yumin Wong*
398
+ *Tom Lord*
480
399
 
481
- * Add `Array#extract!`.
400
+ * `Array#to_sentence` no longer returns a frozen string.
482
401
 
483
- The method removes and returns the elements for which the block returns a true value.
484
- If no block is given, an Enumerator is returned instead.
402
+ Before:
485
403
 
486
- numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
487
- odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
488
- numbers # => [0, 2, 4, 6, 8]
404
+ ['one', 'two'].to_sentence.frozen?
405
+ # => true
489
406
 
490
- *bogdanvlviv*
407
+ After:
491
408
 
492
- * Support not to cache `nil` for `ActiveSupport::Cache#fetch`.
409
+ ['one', 'two'].to_sentence.frozen?
410
+ # => false
493
411
 
494
- cache.fetch('bar', skip_nil: true) { nil }
495
- cache.exist?('bar') # => false
412
+ *Nicolas Dular*
496
413
 
497
- *Martin Hong*
414
+ * When an instance of `ActiveSupport::Duration` is converted to an `iso8601` duration string, if `weeks` are mixed with `date` parts, the `week` part will be converted to days.
415
+ This keeps the parser and serializer on the same page.
498
416
 
499
- * Add "event object" support to the notification system.
500
- Before this change, end users were forced to create hand made artisanal
501
- event objects on their own, like this:
417
+ ```ruby
418
+ duration = ActiveSupport::Duration.build(1000000)
419
+ # 1 week, 4 days, 13 hours, 46 minutes, and 40.0 seconds
502
420
 
503
- ActiveSupport::Notifications.subscribe('wait') do |*args|
504
- @event = ActiveSupport::Notifications::Event.new(*args)
505
- end
421
+ duration_iso = duration.iso8601
422
+ # P11DT13H46M40S
506
423
 
507
- ActiveSupport::Notifications.instrument('wait') do
508
- sleep 1
509
- end
424
+ ActiveSupport::Duration.parse(duration_iso)
425
+ # 11 days, 13 hours, 46 minutes, and 40 seconds
510
426
 
511
- @event.duration # => 1000.138
427
+ duration = ActiveSupport::Duration.build(604800)
428
+ # 1 week
512
429
 
513
- After this change, if the block passed to `subscribe` only takes one
514
- parameter, the framework will yield an event object to the block. Now
515
- end users are no longer required to make their own:
430
+ duration_iso = duration.iso8601
431
+ # P1W
516
432
 
517
- ActiveSupport::Notifications.subscribe('wait') do |event|
518
- @event = event
519
- end
433
+ ActiveSupport::Duration.parse(duration_iso)
434
+ # 1 week
435
+ ```
520
436
 
521
- ActiveSupport::Notifications.instrument('wait') do
522
- sleep 1
523
- end
437
+ *Abhishek Sarkar*
524
438
 
525
- p @event.allocations # => 7
526
- p @event.cpu_time # => 0.256
527
- p @event.idle_time # => 1003.2399
439
+ * Add block support to `ActiveSupport::Testing::TimeHelpers#travel_back`.
528
440
 
529
- Now you can enjoy event objects without making them yourself. Neat!
441
+ *Tim Masliuchenko*
530
442
 
531
- *Aaron "t.lo" Patterson*
443
+ * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
444
+ `ActiveSupport.parse_json_times = true`.
532
445
 
533
- * Add cpu_time, idle_time, and allocations to Event.
446
+ *Christian Gregg*
534
447
 
535
- *Eileen M. Uchitelle*, *Aaron Patterson*
448
+ * Support symbolic links for `content_path` in `ActiveSupport::EncryptedFile`.
536
449
 
537
- * RedisCacheStore: support key expiry in increment/decrement.
450
+ *Takumi Shotoku*
538
451
 
539
- Pass `:expires_in` to `#increment` and `#decrement` to set a Redis EXPIRE on the key.
452
+ * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
453
+ and endless range targets.
540
454
 
541
- If the key is already set to expire, RedisCacheStore won't extend its expiry.
455
+ *Allen Hsu*, *Andrew Hodgkinson*
542
456
 
543
- Rails.cache.increment("some_key", 1, expires_in: 2.minutes)
457
+ * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
544
458
 
545
- *Jason Lee*
459
+ *Iain Beeston*
546
460
 
547
- * Allow `Range#===` and `Range#cover?` on Range.
461
+ * Prevent `ActiveSupport::Duration.build(value)` from creating instances of
462
+ `ActiveSupport::Duration` unless `value` is of type `Numeric`.
548
463
 
549
- `Range#cover?` can now accept a range argument like `Range#include?` and
550
- `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
551
- into a new file, with these two methods.
464
+ Addresses the errant set of behaviours described in #37012 where
465
+ `ActiveSupport::Duration` comparisons would fail confusingly
466
+ or return unexpected results when comparing durations built from instances of `String`.
552
467
 
553
- *Requiring active_support/core_ext/range/include_range is now deprecated.*
554
- *Use `require "active_support/core_ext/range/compare_range"` instead.*
468
+ Before:
555
469
 
556
- *utilum*
470
+ small_duration_from_string = ActiveSupport::Duration.build('9')
471
+ large_duration_from_string = ActiveSupport::Duration.build('100000000000000')
472
+ small_duration_from_int = ActiveSupport::Duration.build(9)
557
473
 
558
- * Add `index_with` to Enumerable.
474
+ large_duration_from_string > small_duration_from_string
475
+ # => false
559
476
 
560
- Allows creating a hash from an enumerable with the value from a passed block
561
- or a default argument.
477
+ small_duration_from_string == small_duration_from_int
478
+ # => false
562
479
 
563
- %i( title body ).index_with { |attr| post.public_send(attr) }
564
- # => { title: "hey", body: "what's up?" }
480
+ small_duration_from_int < large_duration_from_string
481
+ # => ArgumentError (comparison of ActiveSupport::Duration::Scalar with ActiveSupport::Duration failed)
565
482
 
566
- %i( title body ).index_with(nil)
567
- # => { title: nil, body: nil }
483
+ large_duration_from_string > small_duration_from_int
484
+ # => ArgumentError (comparison of String with ActiveSupport::Duration failed)
568
485
 
569
- Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
486
+ After:
570
487
 
571
- *Kasper Timm Hansen*
488
+ small_duration_from_string = ActiveSupport::Duration.build('9')
489
+ # => TypeError (can't build an ActiveSupport::Duration from a String)
572
490
 
573
- * Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
574
- any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
491
+ *Alexei Emam*
575
492
 
576
- *Dominik Sander*
493
+ * Add `ActiveSupport::Cache::Store#delete_multi` method to delete multiple keys from the cache store.
577
494
 
578
- * Redis cache store: `delete_matched` no longer blocks the Redis server.
579
- (Switches from evaled Lua to a batched SCAN + DEL loop.)
495
+ *Peter Zhu*
580
496
 
581
- *Gleb Mazovetskiy*
497
+ * Support multiple arguments in `HashWithIndifferentAccess` for `merge` and `update` methods, to
498
+ follow Ruby 2.6 addition.
582
499
 
583
- * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
584
- size when compression is enabled (which is true by default). This patch
585
- does not attempt to repair existing data: please manually flush the cache
586
- to clear out the problematic entries.
500
+ *Wojciech Wnętrzak*
587
501
 
588
- *Godfrey Chan*
502
+ * Allow initializing `thread_mattr_*` attributes via `:default` option.
589
503
 
590
- * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
504
+ class Scraper
505
+ thread_mattr_reader :client, default: Api::Client.new
506
+ end
591
507
 
592
- URI.unescape("\xe3\x83\x90") # => "バ"
593
- URI.unescape("%E3%83%90") # => "バ"
594
- URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
508
+ *Guilherme Mansur*
595
509
 
596
- *Ashe Connor*, *Aaron Patterson*
510
+ * Add `compact_blank` for those times when you want to remove #blank? values from
511
+ an Enumerable (also `compact_blank!` on Hash, Array, ActionController::Parameters).
597
512
 
598
- * Add `before?` and `after?` methods to `Date`, `DateTime`,
599
- `Time`, and `TimeWithZone`.
513
+ *Dana Sherson*
600
514
 
601
- *Nick Holden*
515
+ * Make ActiveSupport::Logger Fiber-safe.
602
516
 
603
- * `ActiveSupport::Inflector#ordinal` and `ActiveSupport::Inflector#ordinalize` now support
604
- translations through I18n.
517
+ Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
518
+ to make log level local to Ruby Fibers in addition to Threads.
605
519
 
606
- # locale/fr.rb
520
+ Example:
607
521
 
608
- {
609
- fr: {
610
- number: {
611
- nth: {
612
- ordinals: lambda do |_key, number:, **_options|
613
- if number.to_i.abs == 1
614
- 'er'
615
- else
616
- 'e'
617
- end
618
- end,
522
+ logger = ActiveSupport::Logger.new(STDOUT)
523
+ logger.level = 1
524
+ puts "Main is debug? #{logger.debug?}"
619
525
 
620
- ordinalized: lambda do |_key, number:, **_options|
621
- "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
622
- end
623
- }
624
- }
625
- }
626
- }
526
+ Fiber.new {
527
+ logger.local_level = 0
528
+ puts "Thread is debug? #{logger.debug?}"
529
+ }.resume
627
530
 
531
+ puts "Main is debug? #{logger.debug?}"
628
532
 
629
- *Christian Blais*
533
+ Before:
630
534
 
631
- * Add `:private` option to ActiveSupport's `Module#delegate`
632
- in order to delegate methods as private:
535
+ Main is debug? false
536
+ Thread is debug? true
537
+ Main is debug? true
633
538
 
634
- class User < ActiveRecord::Base
635
- has_one :profile
636
- delegate :date_of_birth, to: :profile, private: true
539
+ After:
637
540
 
638
- def age
639
- Date.today.year - date_of_birth.year
640
- end
641
- end
541
+ Main is debug? false
542
+ Thread is debug? true
543
+ Main is debug? false
642
544
 
643
- # User.new.age # => 29
644
- # User.new.date_of_birth
645
- # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
545
+ Fixes #36752.
646
546
 
647
- *Tomas Valent*
547
+ *Alexander Varnin*
648
548
 
649
- * `String#truncate_bytes` to truncate a string to a maximum bytesize without
650
- breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.
549
+ * Allow the `on_rotation` proc used when decrypting/verifying a message to be
550
+ passed at the constructor level.
651
551
 
652
- *Jeremy Daer*
552
+ Before:
653
553
 
654
- * `String#strip_heredoc` preserves frozenness.
554
+ crypt = ActiveSupport::MessageEncryptor.new('long_secret')
555
+ crypt.decrypt_and_verify(encrypted_message, on_rotation: proc { ... })
556
+ crypt.decrypt_and_verify(another_encrypted_message, on_rotation: proc { ... })
655
557
 
656
- "foo".freeze.strip_heredoc.frozen? # => true
558
+ After:
657
559
 
658
- Fixes that frozen string literals would inadvertently become unfrozen:
560
+ crypt = ActiveSupport::MessageEncryptor.new('long_secret', on_rotation: proc { ... })
561
+ crypt.decrypt_and_verify(encrypted_message)
562
+ crypt.decrypt_and_verify(another_encrypted_message)
659
563
 
660
- # frozen_string_literal: true
564
+ *Edouard Chin*
661
565
 
662
- foo = <<-MSG.strip_heredoc
663
- la la la
664
- MSG
566
+ * `delegate_missing_to` would raise a `DelegationError` if the object
567
+ delegated to was `nil`. Now the `allow_nil` option has been added to enable
568
+ the user to specify they want `nil` returned in this case.
665
569
 
666
- foo.frozen? # => false !??
570
+ *Matthew Tanous*
667
571
 
668
- *Jeremy Daer*
572
+ * `truncate` would return the original string if it was too short to be truncated
573
+ and a frozen string if it were long enough to be truncated. Now truncate will
574
+ consistently return an unfrozen string regardless. This behavior is consistent
575
+ with `gsub` and `strip`.
669
576
 
670
- * Rails 6 requires Ruby 2.5.0 or newer.
577
+ Before:
671
578
 
672
- *Jeremy Daer*, *Kasper Timm Hansen*
579
+ 'foobar'.truncate(5).frozen?
580
+ # => true
581
+ 'foobar'.truncate(6).frozen?
582
+ # => false
673
583
 
674
- * Adds parallel testing to Rails.
584
+ After:
675
585
 
676
- Parallelize your test suite with forked processes or threads.
586
+ 'foobar'.truncate(5).frozen?
587
+ # => false
588
+ 'foobar'.truncate(6).frozen?
589
+ # => false
677
590
 
678
- *Eileen M. Uchitelle*, *Aaron Patterson*
591
+ *Jordan Thomas*
679
592
 
680
593
 
681
- Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activesupport/CHANGELOG.md) for previous changes.
594
+ Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activesupport/CHANGELOG.md) for previous changes.