activesupport 5.2.8.1 → 6.0.6

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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +467 -410
  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/backtrace_cleaner.rb +27 -1
  7. data/lib/active_support/cache/file_store.rb +32 -32
  8. data/lib/active_support/cache/mem_cache_store.rb +12 -7
  9. data/lib/active_support/cache/memory_store.rb +15 -9
  10. data/lib/active_support/cache/null_store.rb +8 -3
  11. data/lib/active_support/cache/redis_cache_store.rb +47 -20
  12. data/lib/active_support/cache/strategy/local_cache.rb +22 -22
  13. data/lib/active_support/cache.rb +71 -48
  14. data/lib/active_support/callbacks.rb +16 -8
  15. data/lib/active_support/concern.rb +24 -1
  16. data/lib/active_support/concurrency/share_lock.rb +0 -1
  17. data/lib/active_support/configurable.rb +7 -11
  18. data/lib/active_support/core_ext/array/access.rb +18 -6
  19. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  20. data/lib/active_support/core_ext/array/extract.rb +21 -0
  21. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  22. data/lib/active_support/core_ext/array.rb +1 -1
  23. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  24. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  25. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  26. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  27. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  28. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  29. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  30. data/lib/active_support/core_ext/enumerable.rb +97 -73
  31. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  32. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  33. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  34. data/lib/active_support/core_ext/hash/except.rb +2 -2
  35. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  36. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  37. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  38. data/lib/active_support/core_ext/hash.rb +1 -2
  39. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  40. data/lib/active_support/core_ext/kernel.rb +0 -1
  41. data/lib/active_support/core_ext/load_error.rb +1 -1
  42. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  43. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  44. data/lib/active_support/core_ext/module/delegation.rb +41 -8
  45. data/lib/active_support/core_ext/module/introspection.rb +38 -13
  46. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  47. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  48. data/lib/active_support/core_ext/module.rb +0 -1
  49. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  50. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  51. data/lib/active_support/core_ext/numeric.rb +0 -1
  52. data/lib/active_support/core_ext/object/blank.rb +1 -2
  53. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  54. data/lib/active_support/core_ext/object/json.rb +2 -1
  55. data/lib/active_support/core_ext/object/try.rb +17 -7
  56. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  57. data/lib/active_support/core_ext/range/compare_range.rb +28 -13
  58. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  59. data/lib/active_support/core_ext/range/each.rb +0 -1
  60. data/lib/active_support/core_ext/range/include_range.rb +6 -0
  61. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  62. data/lib/active_support/core_ext/regexp.rb +0 -4
  63. data/lib/active_support/core_ext/securerandom.rb +23 -3
  64. data/lib/active_support/core_ext/string/access.rb +8 -0
  65. data/lib/active_support/core_ext/string/filters.rb +42 -1
  66. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  67. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  68. data/lib/active_support/core_ext/string/output_safety.rb +68 -10
  69. data/lib/active_support/core_ext/string/strip.rb +3 -1
  70. data/lib/active_support/core_ext/time/calculations.rb +34 -3
  71. data/lib/active_support/core_ext/uri.rb +1 -0
  72. data/lib/active_support/current_attributes.rb +8 -0
  73. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  74. data/lib/active_support/dependencies.rb +74 -18
  75. data/lib/active_support/deprecation/behaviors.rb +1 -1
  76. data/lib/active_support/deprecation/method_wrappers.rb +17 -23
  77. data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
  78. data/lib/active_support/deprecation.rb +1 -1
  79. data/lib/active_support/descendants_tracker.rb +55 -9
  80. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  81. data/lib/active_support/duration/iso8601_serializer.rb +3 -5
  82. data/lib/active_support/duration.rb +7 -8
  83. data/lib/active_support/encrypted_configuration.rb +0 -4
  84. data/lib/active_support/encrypted_file.rb +3 -2
  85. data/lib/active_support/evented_file_update_checker.rb +39 -10
  86. data/lib/active_support/execution_wrapper.rb +2 -1
  87. data/lib/active_support/file_update_checker.rb +0 -1
  88. data/lib/active_support/gem_version.rb +4 -4
  89. data/lib/active_support/hash_with_indifferent_access.rb +22 -18
  90. data/lib/active_support/i18n.rb +1 -0
  91. data/lib/active_support/i18n_railtie.rb +13 -1
  92. data/lib/active_support/inflector/inflections.rb +1 -5
  93. data/lib/active_support/inflector/methods.rb +16 -29
  94. data/lib/active_support/inflector/transliterate.rb +47 -18
  95. data/lib/active_support/json/decoding.rb +23 -24
  96. data/lib/active_support/json/encoding.rb +6 -2
  97. data/lib/active_support/key_generator.rb +0 -32
  98. data/lib/active_support/lazy_load_hooks.rb +5 -2
  99. data/lib/active_support/locale/en.rb +33 -0
  100. data/lib/active_support/log_subscriber.rb +31 -9
  101. data/lib/active_support/logger.rb +1 -16
  102. data/lib/active_support/logger_silence.rb +28 -12
  103. data/lib/active_support/logger_thread_safe_level.rb +26 -4
  104. data/lib/active_support/message_encryptor.rb +4 -6
  105. data/lib/active_support/message_verifier.rb +5 -5
  106. data/lib/active_support/messages/metadata.rb +11 -2
  107. data/lib/active_support/messages/rotator.rb +4 -4
  108. data/lib/active_support/multibyte/chars.rb +29 -49
  109. data/lib/active_support/multibyte/unicode.rb +44 -282
  110. data/lib/active_support/notifications/fanout.rb +98 -13
  111. data/lib/active_support/notifications/instrumenter.rb +80 -9
  112. data/lib/active_support/notifications.rb +41 -4
  113. data/lib/active_support/number_helper/number_converter.rb +4 -5
  114. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
  115. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  116. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
  117. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
  118. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  119. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  120. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
  121. data/lib/active_support/number_helper/rounding_helper.rb +1 -1
  122. data/lib/active_support/number_helper.rb +11 -0
  123. data/lib/active_support/option_merger.rb +21 -3
  124. data/lib/active_support/ordered_hash.rb +1 -1
  125. data/lib/active_support/ordered_options.rb +5 -1
  126. data/lib/active_support/parameter_filter.rb +128 -0
  127. data/lib/active_support/rails.rb +0 -6
  128. data/lib/active_support/reloader.rb +4 -5
  129. data/lib/active_support/security_utils.rb +1 -1
  130. data/lib/active_support/string_inquirer.rb +0 -1
  131. data/lib/active_support/subscriber.rb +65 -26
  132. data/lib/active_support/tagged_logging.rb +13 -4
  133. data/lib/active_support/test_case.rb +91 -0
  134. data/lib/active_support/testing/assertions.rb +15 -1
  135. data/lib/active_support/testing/deprecation.rb +0 -1
  136. data/lib/active_support/testing/file_fixtures.rb +2 -0
  137. data/lib/active_support/testing/isolation.rb +2 -2
  138. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  139. data/lib/active_support/testing/parallelization.rb +134 -0
  140. data/lib/active_support/testing/stream.rb +1 -2
  141. data/lib/active_support/testing/time_helpers.rb +7 -9
  142. data/lib/active_support/time_with_zone.rb +15 -5
  143. data/lib/active_support/values/time_zone.rb +12 -7
  144. data/lib/active_support/xml_mini/jdom.rb +2 -3
  145. data/lib/active_support/xml_mini/libxml.rb +2 -2
  146. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  147. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  148. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  149. data/lib/active_support/xml_mini/rexml.rb +2 -2
  150. data/lib/active_support/xml_mini.rb +2 -10
  151. data/lib/active_support.rb +2 -1
  152. metadata +37 -8
  153. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  154. data/lib/active_support/values/unicode_tables.dat +0 -0
data/CHANGELOG.md CHANGED
@@ -1,14 +1,19 @@
1
- ## Rails 5.2.8.1 (July 12, 2022) ##
1
+ ## Rails 6.0.6 (September 09, 2022) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 5.2.8 (May 09, 2022) ##
6
+ ## Rails 6.0.5.1 (July 12, 2022) ##
7
7
 
8
8
  * No changes.
9
9
 
10
10
 
11
- ## Rails 5.2.7.1 (April 26, 2022) ##
11
+ ## Rails 6.0.5 (May 09, 2022) ##
12
+
13
+ * No changes.
14
+
15
+
16
+ ## Rails 6.0.4.8 (April 26, 2022) ##
12
17
 
13
18
  * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
14
19
 
@@ -18,70 +23,190 @@
18
23
  *Álvaro Martín Fraguas*
19
24
 
20
25
 
21
- ## Rails 5.2.7 (March 10, 2022) ##
26
+ ## Rails 6.0.4.7 (March 08, 2022) ##
27
+
28
+ * No changes.
29
+
30
+
31
+ ## Rails 6.0.4.6 (February 11, 2022) ##
32
+
33
+ * Fix Reloader method signature to work with the new Executor signature
22
34
 
23
- * Restore support to Ruby 2.2.
24
35
 
25
- *ojab*
36
+ ## Rails 6.0.4.5 (February 11, 2022) ##
26
37
 
38
+ * No changes.
27
39
 
28
- ## Rails 5.2.6.3 (March 08, 2022) ##
40
+
41
+ ## Rails 6.0.4.4 (December 15, 2021) ##
29
42
 
30
43
  * No changes.
31
44
 
32
45
 
33
- ## Rails 5.2.6.2 (February 11, 2022) ##
46
+ ## Rails 6.0.4.3 (December 14, 2021) ##
34
47
 
35
- * Fix Reloader method signature to work with the new Executor signature
48
+ * No changes.
49
+
50
+
51
+ ## Rails 6.0.4.2 (December 14, 2021) ##
52
+
53
+ * No changes.
54
+
55
+
56
+ ## Rails 6.0.4.1 (August 19, 2021) ##
57
+
58
+ * No changes.
59
+
60
+
61
+ ## Rails 6.0.4 (June 15, 2021) ##
62
+
63
+ * Fixed issue in `ActiveSupport::Cache::RedisCacheStore` not passing options
64
+ to `read_multi` causing `fetch_multi` to not work properly.
65
+
66
+ *Rajesh Sharma*
67
+
68
+ * `with_options` copies its options hash again to avoid leaking mutations.
36
69
 
70
+ Fixes #39343.
37
71
 
38
- ## Rails 5.2.6.1 (February 11, 2022) ##
72
+ *Eugene Kenny*
73
+
74
+
75
+ ## Rails 6.0.3.7 (May 05, 2021) ##
39
76
 
40
77
  * No changes.
41
78
 
42
79
 
43
- ## Rails 5.2.6 (May 05, 2021) ##
80
+ ## Rails 6.0.3.6 (March 26, 2021) ##
44
81
 
45
82
  * No changes.
46
83
 
47
84
 
48
- ## Rails 5.2.5 (March 26, 2021) ##
85
+ ## Rails 6.0.3.5 (February 10, 2021) ##
49
86
 
50
87
  * No changes.
51
88
 
52
89
 
53
- ## Rails 5.2.4.6 (May 05, 2021) ##
90
+ ## Rails 6.0.3.4 (October 07, 2020) ##
54
91
 
55
92
  * No changes.
56
93
 
57
94
 
58
- ## Rails 5.2.4.5 (February 10, 2021) ##
95
+ ## Rails 6.0.3.3 (September 09, 2020) ##
59
96
 
60
97
  * No changes.
61
98
 
62
99
 
63
- ## Rails 5.2.4.4 (September 09, 2020) ##
100
+ ## Rails 6.0.3.2 (June 17, 2020) ##
64
101
 
65
102
  * No changes.
66
103
 
67
104
 
68
- ## Rails 5.2.4.3 (May 18, 2020) ##
105
+ ## Rails 6.0.3.1 (May 18, 2020) ##
69
106
 
70
107
  * [CVE-2020-8165] Deprecate Marshal.load on raw cache read in RedisCacheStore
71
108
 
72
109
  * [CVE-2020-8165] Avoid Marshal.load on raw cache value in MemCacheStore
73
110
 
74
- ## Rails 5.2.4.2 (March 19, 2020) ##
111
+
112
+ ## Rails 6.0.3 (May 06, 2020) ##
113
+
114
+ * `Array#to_sentence` no longer returns a frozen string.
115
+
116
+ Before:
117
+
118
+ ['one', 'two'].to_sentence.frozen?
119
+ # => true
120
+
121
+ After:
122
+
123
+ ['one', 'two'].to_sentence.frozen?
124
+ # => false
125
+
126
+ *Nicolas Dular*
127
+
128
+ * Update `ActiveSupport::Messages::Metadata#fresh?` to work for cookies with expiry set when
129
+ `ActiveSupport.parse_json_times = true`.
130
+
131
+ *Christian Gregg*
132
+
133
+
134
+ ## Rails 6.0.2.2 (March 19, 2020) ##
75
135
 
76
136
  * No changes.
77
137
 
78
138
 
79
- ## Rails 5.2.4.1 (December 18, 2019) ##
139
+ ## Rails 6.0.2.1 (December 18, 2019) ##
80
140
 
81
141
  * No changes.
82
142
 
83
143
 
84
- ## Rails 5.2.4 (November 27, 2019) ##
144
+ ## Rails 6.0.2 (December 13, 2019) ##
145
+
146
+ * Eager load translations during initialization.
147
+
148
+ *Diego Plentz*
149
+
150
+ * Use per-thread CPU time clock on `ActiveSupport::Notifications`.
151
+
152
+ *George Claghorn*
153
+
154
+
155
+ ## Rails 6.0.1 (November 5, 2019) ##
156
+
157
+ * `ActiveSupport::SafeBuffer` supports `Enumerator` methods.
158
+
159
+ *Shugo Maeda*
160
+
161
+ * The Redis cache store fails gracefully when the server returns a "max number
162
+ of clients reached" error.
163
+
164
+ *Brandon Medenwald*
165
+
166
+ * Fixed that mutating a value returned by a memory cache store would
167
+ unexpectedly change the cached value.
168
+
169
+ *Jonathan Hyman*
170
+
171
+ * The default inflectors in `zeitwerk` mode support overrides:
172
+
173
+ ```ruby
174
+ # config/initializers/zeitwerk.rb
175
+ Rails.autoloaders.each do |autoloader|
176
+ autoloader.inflector.inflect(
177
+ "html_parser" => "HTMLParser",
178
+ "ssl_error" => "SSLError"
179
+ )
180
+ end
181
+ ```
182
+
183
+ 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.
184
+
185
+ 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.
186
+
187
+ *Xavier Noria*
188
+
189
+ * Improve `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
190
+ and endless range targets.
191
+
192
+ *Allen Hsu*, *Andrew Hodgkinson*
193
+
194
+ * Don't use `Process#clock_gettime(CLOCK_THREAD_CPUTIME_ID)` on Solaris.
195
+
196
+ *Iain Beeston*
197
+
198
+
199
+ ## Rails 6.0.0 (August 16, 2019) ##
200
+
201
+ * Let `require_dependency` in `zeitwerk` mode look the autoload paths up for
202
+ better backwards compatibility.
203
+
204
+ *Xavier Noria*
205
+
206
+ * Let `require_dependency` in `zeitwerk` mode support arguments that respond
207
+ to `to_path` for better backwards compatibility.
208
+
209
+ *Xavier Noria*
85
210
 
86
211
  * Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
87
212
 
@@ -115,606 +240,538 @@
115
240
 
116
241
  *Alexander Varnin*
117
242
 
243
+ * Do not delegate missing `marshal_dump` and `_dump` methods via the
244
+ `delegate_missing_to` extension. This avoids unintentionally adding instance
245
+ variables when calling `Marshal.dump(object)`, should the delegation target of
246
+ `object` be a method which would otherwise add them. Fixes #36522.
118
247
 
119
- ## Rails 5.2.3 (March 27, 2019) ##
248
+ *Aaron Lipman*
120
249
 
121
- * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
122
250
 
123
- `assoc` can now be called with either a string or a symbol.
251
+ ## Rails 6.0.0.rc2 (July 22, 2019) ##
124
252
 
125
- *Stefan Schüßler*
253
+ * `truncate` would return the original string if it was too short to be truncated
254
+ and a frozen string if it were long enough to be truncated. Now truncate will
255
+ consistently return an unfrozen string regardless. This behavior is consistent
256
+ with `gsub` and `strip`.
126
257
 
127
- * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
258
+ Before:
128
259
 
129
- *Keenan Brock*
260
+ 'foobar'.truncate(5).frozen?
261
+ # => true
262
+ 'foobar'.truncate(6).frozen?
263
+ # => false
130
264
 
131
- * Allow Range#=== and Range#cover? on Range
265
+ After:
132
266
 
133
- `Range#cover?` can now accept a range argument like `Range#include?` and
134
- `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
135
- into a new file, with these two methods.
267
+ 'foobar'.truncate(5).frozen?
268
+ # => false
269
+ 'foobar'.truncate(6).frozen?
270
+ # => false
136
271
 
137
- *utilum*
272
+ *Jordan Thomas*
138
273
 
139
- * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
140
274
 
141
- *Mark J. Titorenko*, *Vlad Bokov*
275
+ ## Rails 6.0.0.rc1 (April 24, 2019) ##
142
276
 
277
+ * Speed improvements to `Hash.except` and `HashWithIndifferentAccess#except`.
143
278
 
144
- ## Rails 5.2.2.1 (March 11, 2019) ##
279
+ These methods now unset the `default`/`default_proc` on the returned Hash, compatible with Ruby 3.0’s native implementation.
145
280
 
146
- * No changes.
281
+ *Timo Schilling*
147
282
 
283
+ * Introduce `ActiveSupport::ActionableError`.
148
284
 
149
- ## Rails 5.2.2 (December 04, 2018) ##
285
+ Actionable errors let's you dispatch actions from Rails' error pages. This
286
+ can help you save time if you have a clear action for the resolution of
287
+ common development errors.
150
288
 
151
- * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
152
- would not act as alias for `#symbolize_keys`.
289
+ The de-facto example are pending migrations. Every time pending migrations
290
+ are found, a middleware raises an error. With actionable errors, you can
291
+ run the migrations right from the error page. Other examples include Rails
292
+ plugins that need to run a rake task to setup themselves. They can now
293
+ raise actionable errors to run the setup straight from the error pages.
153
294
 
154
- *Nick Weiland*
295
+ Here is how to define an actionable error:
155
296
 
156
- * Improve the logic that detects non-autoloaded constants.
297
+ ```ruby
298
+ class PendingMigrationError < MigrationError #:nodoc:
299
+ include ActiveSupport::ActionableError
157
300
 
158
- *Jan Habermann*, *Xavier Noria*
301
+ action "Run pending migrations" do
302
+ ActiveRecord::Tasks::DatabaseTasks.migrate
303
+ end
304
+ end
305
+ ```
159
306
 
160
- * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
307
+ To make an error actionable, include the `ActiveSupport::ActionableError`
308
+ module and invoke the `action` class macro to define the action. An action
309
+ needs a name and a procedure to execute. The name is shown as the name of a
310
+ button on the error pages. Once clicked, it will invoke the given
311
+ procedure.
161
312
 
162
- URI.unescape("\xe3\x83\x90") # => "バ"
163
- URI.unescape("%E3%83%90") # => "バ"
164
- URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
313
+ *Vipul A M*, *Yao Jie*, *Genadi Samokovarov*
165
314
 
166
- *Ashe Connor*, *Aaron Patterson*
315
+ * Preserve `html_safe?` status on `ActiveSupport::SafeBuffer#*`.
167
316
 
317
+ Before:
168
318
 
169
- ## Rails 5.2.1.1 (November 27, 2018) ##
319
+ ("<br />".html_safe * 2).html_safe? #=> nil
170
320
 
171
- * No changes.
321
+ After:
172
322
 
323
+ ("<br />".html_safe * 2).html_safe? #=> true
173
324
 
174
- ## Rails 5.2.1 (August 07, 2018) ##
325
+ *Ryo Nakamura*
175
326
 
176
- * Redis cache store: `delete_matched` no longer blocks the Redis server.
177
- (Switches from evaled Lua to a batched SCAN + DEL loop.)
327
+ * Calling test methods with `with_info_handler` method to allow minitest-hooks
328
+ plugin to work.
178
329
 
179
- *Gleb Mazovetskiy*
330
+ *Mauri Mustonen*
180
331
 
181
- * Fix bug where `ActiveSupport::Timezone.all` would fail when tzinfo data for
182
- any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
332
+ * The Zeitwerk compatibility interface for `ActiveSupport::Dependencies` no
333
+ longer implements `autoloaded_constants` or `autoloaded?` (undocumented,
334
+ anyway). Experience shows introspection does not have many use cases, and
335
+ troubleshooting is done by logging. With this design trade-off we are able
336
+ to use even less memory in all environments.
183
337
 
184
- *Dominik Sander*
338
+ *Xavier Noria*
185
339
 
186
- * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
187
- size when compression is enabled (which is true by default). This patch
188
- does not attempt to repair existing data: please manually flush the cache
189
- to clear out the problematic entries.
340
+ * Depends on Zeitwerk 2, which stores less metadata if reloading is disabled
341
+ and hence uses less memory when `config.cache_classes` is `true`, a standard
342
+ setup in production.
190
343
 
191
- *Godfrey Chan*
344
+ *Xavier Noria*
192
345
 
193
- * Fix `ActiveSupport::Cache#read_multi` bug with local cache enabled that was
194
- returning instances of `ActiveSupport::Cache::Entry` instead of the raw values.
346
+ * In `:zeitwerk` mode, eager load directories in engines and applications only
347
+ if present in their respective `config.eager_load_paths`.
195
348
 
196
- *Jason Lee*
349
+ A common use case for this is adding `lib` to `config.autoload_paths`, but
350
+ not to `config.eager_load_paths`. In that configuration, for example, files
351
+ in the `lib` directory should not be eager loaded.
197
352
 
353
+ *Xavier Noria*
198
354
 
199
- ## Rails 5.2.0 (April 09, 2018) ##
355
+ * Fix bug in Range comparisons when comparing to an excluded-end Range
200
356
 
201
- * Caching: MemCache and Redis `read_multi` and `fetch_multi` speedup.
202
- Read from the local in-memory cache before consulting the backend.
357
+ Before:
203
358
 
204
- *Gabriel Sobrinho*
359
+ (1..10).cover?(1...11) # => false
205
360
 
206
- * Return all mappings for a timezone identifier in `country_zones`.
361
+ After:
207
362
 
208
- Some timezones like `Europe/London` have multiple mappings in
209
- `ActiveSupport::TimeZone::MAPPING` so return all of them instead
210
- of the first one found by using `Hash#value`. e.g:
363
+ (1..10).cover?(1...11) # => true
211
364
 
212
- # Before
213
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh"]
365
+ With the same change for `Range#include?` and `Range#===`.
214
366
 
215
- # After
216
- ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh", "London"]
367
+ *Owen Stephens*
217
368
 
218
- Fixes #31668.
369
+ * Use weak references in descendants tracker to allow anonymous subclasses to
370
+ be garbage collected.
219
371
 
220
- *Andrew White*
372
+ *Edgars Beigarts*
221
373
 
222
- * Add support for connection pooling on RedisCacheStore.
374
+ * Update `ActiveSupport::Notifications::Instrumenter#instrument` to make
375
+ passing a block optional. This will let users use
376
+ `ActiveSupport::Notifications` messaging features outside of
377
+ instrumentation.
223
378
 
224
- *fatkodima*
379
+ *Ali Ibrahim*
225
380
 
226
- * Support hash as first argument in `assert_difference`. This allows to specify multiple
227
- numeric differences in the same assertion.
381
+ * Fix `Time#advance` to work with dates before 1001-03-07
228
382
 
229
- assert_difference ->{ Article.count } => 1, ->{ Post.count } => 2
383
+ Before:
230
384
 
231
- *Julien Meichelbeck*
385
+ Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
232
386
 
233
- * Add missing instrumentation for `read_multi` in `ActiveSupport::Cache::Store`.
387
+ After
234
388
 
235
- *Ignatius Reza Lesmana*
389
+ Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC
236
390
 
237
- * `assert_changes` will always assert that the expression changes,
238
- regardless of `from:` and `to:` argument combinations.
391
+ Note that this doesn't affect `DateTime#advance` as that doesn't use a proleptic calendar.
239
392
 
240
- *Daniel Ma*
393
+ *Andrew White*
241
394
 
242
- * Use SHA-1 to generate non-sensitive digests, such as the ETag header.
395
+ * 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.
243
396
 
244
- Enabled by default for new apps; upgrading apps can opt in by setting
245
- `config.active_support.use_sha1_digests = true`.
397
+ *Xavier Noria*
246
398
 
247
- *Dmitri Dolguikh*, *Eugene Kenny*
399
+ * Add support for supplying `locale` to `transliterate` and `parameterize`.
248
400
 
249
- * Changed default behaviour of `ActiveSupport::SecurityUtils.secure_compare`,
250
- to make it not leak length information even for variable length string.
401
+ I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })
251
402
 
252
- Renamed old `ActiveSupport::SecurityUtils.secure_compare` to `fixed_length_secure_compare`,
253
- and started raising `ArgumentError` in case of length mismatch of passed strings.
403
+ ActiveSupport::Inflector.transliterate("ü", locale: :de) # => "ue"
404
+ "Fünf autos".parameterize(locale: :de) # => "fuenf-autos"
405
+ ActiveSupport::Inflector.parameterize("Fünf autos", locale: :de) # => "fuenf-autos"
254
406
 
255
- *Vipul A M*
407
+ *Kaan Ozkan*, *Sharang Dashputre*
256
408
 
257
- * Make `ActiveSupport::TimeZone.all` return only time zones that are in
258
- `ActiveSupport::TimeZone::MAPPING`.
409
+ * Allow `Array#excluding` and `Enumerable#excluding` to deal with a passed array gracefully.
259
410
 
260
- Fixes #7245.
411
+ [ 1, 2, 3, 4, 5 ].excluding([4, 5]) # => [ 1, 2, 3 ]
261
412
 
262
- *Chris LaRose*
413
+ *DHH*
263
414
 
264
- * MemCacheStore: Support expiring counters.
415
+ * Renamed `Array#without` and `Enumerable#without` to `Array#excluding` and `Enumerable#excluding`, to create parity with
416
+ `Array#including` and `Enumerable#including`. Retained the old names as aliases.
265
417
 
266
- Pass `expires_in: [seconds]` to `#increment` and `#decrement` options
267
- to set the Memcached TTL (time-to-live) if the counter doesn't exist.
268
- If the counter exists, Memcached doesn't extend its expiry when it's
269
- incremented or decremented.
418
+ *DHH*
270
419
 
271
- ```
272
- Rails.cache.increment("my_counter", 1, expires_in: 2.minutes)
273
- ```
420
+ * Added `Array#including` and `Enumerable#including` to conveniently enlarge a collection with more members using a method rather than an operator:
274
421
 
275
- *Takumasa Ochi*
422
+ [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
423
+ post.authors.including(Current.person) # => All the authors plus the current person!
276
424
 
277
- * Handle `TZInfo::AmbiguousTime` errors.
425
+ *DHH*
278
426
 
279
- Make `ActiveSupport::TimeWithZone` match Ruby's handling of ambiguous
280
- times by choosing the later period, e.g.
281
427
 
282
- Ruby:
283
- ```
284
- ENV["TZ"] = "Europe/Moscow"
285
- Time.local(2014, 10, 26, 1, 0, 0) # => 2014-10-26 01:00:00 +0300
286
- ```
428
+ ## Rails 6.0.0.beta3 (March 11, 2019) ##
287
429
 
288
- Before:
289
- ```
290
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
291
- TZInfo::AmbiguousTime: 26/10/2014 01:00 is an ambiguous local time.
292
- ```
293
-
294
- After:
295
- ```
296
- >> "2014-10-26 01:00:00".in_time_zone("Moscow")
297
- => Sun, 26 Oct 2014 01:00:00 MSK +03:00
298
- ```
430
+ * No changes.
299
431
 
300
- Fixes #17395.
301
432
 
302
- *Andrew White*
433
+ ## Rails 6.0.0.beta2 (February 25, 2019) ##
303
434
 
304
- * Redis cache store.
435
+ * New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).
305
436
 
306
- ```
307
- # Defaults to `redis://localhost:6379/0`. Only use for dev/test.
308
- config.cache_store = :redis_cache_store
309
-
310
- # Supports all common cache store options (:namespace, :compress,
311
- # :compress_threshold, :expires_in, :race_condition_ttl) and all
312
- # Redis options.
313
- cache_password = Rails.application.secrets.redis_cache_password
314
- config.cache_store = :redis_cache_store, driver: :hiredis,
315
- namespace: 'myapp-cache', compress: true, timeout: 1,
316
- url: "redis://:#{cache_password}@myapp-cache-1:6379/0"
317
-
318
- # Supports Redis::Distributed with multiple hosts
319
- config.cache_store = :redis_cache_store, driver: :hiredis
320
- namespace: 'myapp-cache', compress: true,
321
- url: %w[
322
- redis://myapp-cache-1:6379/0
323
- redis://myapp-cache-1:6380/0
324
- redis://myapp-cache-2:6379/0
325
- redis://myapp-cache-2:6380/0
326
- redis://myapp-cache-3:6379/0
327
- redis://myapp-cache-3:6380/0
328
- ]
329
-
330
- # Or pass a builder block
331
- config.cache_store = :redis_cache_store,
332
- namespace: 'myapp-cache', compress: true,
333
- redis: -> { Redis.new … }
334
- ```
437
+ *Xavier Noria*
335
438
 
336
- Deployment note: Take care to use a *dedicated Redis cache* rather
337
- than pointing this at your existing Redis server. It won't cope well
338
- with mixed usage patterns and it won't expire cache entries by default.
439
+ * Revise `ActiveSupport::Notifications.unsubscribe` to correctly handle Regex or other multiple-pattern subscribers.
339
440
 
340
- Redis cache server setup guide: https://redis.io/topics/lru-cache
441
+ *Zach Kemp*
341
442
 
342
- *Jeremy Daer*
443
+ * Add `before_reset` callback to `CurrentAttributes` and define `after_reset` as an alias of `resets` for symmetry.
343
444
 
344
- * Cache: Enable compression by default for values > 1kB.
445
+ *Rosa Gutierrez*
345
446
 
346
- Compression has long been available, but opt-in and at a 16kB threshold.
347
- It wasn't enabled by default due to CPU cost. Today it's cheap and typical
348
- cache data is eminently compressible, such as HTML or JSON fragments.
349
- Compression dramatically reduces Memcached/Redis mem usage, which means
350
- the same cache servers can store more data, which means higher hit rates.
447
+ * Remove the `` Kernel#` `` override that suppresses ENOENT and accidentally returns nil on Unix systems.
351
448
 
352
- To disable compression, pass `compress: false` to the initializer.
449
+ *Akinori Musha*
353
450
 
354
- *Jeremy Daer*
451
+ * Add `ActiveSupport::HashWithIndifferentAccess#assoc`.
355
452
 
356
- * Allow `Range#include?` on TWZ ranges.
453
+ `assoc` can now be called with either a string or a symbol.
357
454
 
358
- In #11474 we prevented TWZ ranges being iterated over which matched
359
- Ruby's handling of Time ranges and as a consequence `include?`
360
- stopped working with both Time ranges and TWZ ranges. However in
361
- ruby/ruby@b061634 support was added for `include?` to use `cover?`
362
- for 'linear' objects. Since we have no way of making Ruby consider
363
- TWZ instances as 'linear' we have to override `Range#include?`.
455
+ *Stefan Schüßler*
364
456
 
365
- Fixes #30799.
457
+ * Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.
366
458
 
367
- *Andrew White*
459
+ *Guillermo Iguaran*
368
460
 
369
- * Fix acronym support in `humanize`.
370
461
 
371
- Acronym inflections are stored with lowercase keys in the hash but
372
- the match wasn't being lowercased before being looked up in the hash.
373
- This shouldn't have any performance impact because before it would
374
- fail to find the acronym and perform the `downcase` operation anyway.
462
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
375
463
 
376
- Fixes #31052.
464
+ * Remove deprecated `Module#reachable?` method.
377
465
 
378
- *Andrew White*
379
-
380
- * Add same method signature for `Time#prev_year` and `Time#next_year`
381
- in accordance with `Date#prev_year`, `Date#next_year`.
466
+ *Rafael Mendonça França*
382
467
 
383
- Allows pass argument for `Time#prev_year` and `Time#next_year`.
468
+ * Remove deprecated `#acronym_regex` method from `Inflections`.
384
469
 
385
- Before:
386
- ```
387
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
388
- Time.new(2017, 9, 16, 17, 0).prev_year(1)
389
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
470
+ *Rafael Mendonça França*
390
471
 
391
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
392
- Time.new(2017, 9, 16, 17, 0).next_year(1)
393
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
394
- ```
472
+ * Fix `String#safe_constantize` throwing a `LoadError` for incorrectly cased constant references.
395
473
 
396
- After:
397
- ```
398
- Time.new(2017, 9, 16, 17, 0).prev_year # => 2016-09-16 17:00:00 +0300
399
- Time.new(2017, 9, 16, 17, 0).prev_year(1) # => 2016-09-16 17:00:00 +0300
474
+ *Keenan Brock*
400
475
 
401
- Time.new(2017, 9, 16, 17, 0).next_year # => 2018-09-16 17:00:00 +0300
402
- Time.new(2017, 9, 16, 17, 0).next_year(1) # => 2018-09-16 17:00:00 +0300
403
- ```
476
+ * Preserve key order passed to `ActiveSupport::CacheStore#fetch_multi`.
404
477
 
405
- *bogdanvlviv*
478
+ `fetch_multi(*names)` now returns its results in the same order as the `*names` requested, rather than returning cache hits followed by cache misses.
406
479
 
407
- * Add same method signature for `Time#prev_month` and `Time#next_month`
408
- in accordance with `Date#prev_month`, `Date#next_month`.
480
+ *Gannon McGibbon*
409
481
 
410
- Allows pass argument for `Time#prev_month` and `Time#next_month`.
482
+ * If the same block is `included` multiple times for a Concern, an exception is no longer raised.
411
483
 
412
- Before:
413
- ```
414
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
415
- Time.new(2017, 9, 16, 17, 0).prev_month(1)
416
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
484
+ *Mark J. Titorenko*, *Vlad Bokov*
417
485
 
418
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
419
- Time.new(2017, 9, 16, 17, 0).next_month(1)
420
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
421
- ```
486
+ * Fix bug where `#to_options` for `ActiveSupport::HashWithIndifferentAccess`
487
+ would not act as alias for `#symbolize_keys`.
422
488
 
423
- After:
424
- ```
425
- Time.new(2017, 9, 16, 17, 0).prev_month # => 2017-08-16 17:00:00 +0300
426
- Time.new(2017, 9, 16, 17, 0).prev_month(1) # => 2017-08-16 17:00:00 +0300
489
+ *Nick Weiland*
427
490
 
428
- Time.new(2017, 9, 16, 17, 0).next_month # => 2017-10-16 17:00:00 +0300
429
- Time.new(2017, 9, 16, 17, 0).next_month(1) # => 2017-10-16 17:00:00 +0300
430
- ```
491
+ * Improve the logic that detects non-autoloaded constants.
431
492
 
432
- *bogdanvlviv*
493
+ *Jan Habermann*, *Xavier Noria*
433
494
 
434
- * Add same method signature for `Time#prev_day` and `Time#next_day`
435
- in accordance with `Date#prev_day`, `Date#next_day`.
495
+ * Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` and `ActiveSupport::Multibyte::Unicode#unpack_graphemes(string)`
496
+ in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively.
436
497
 
437
- Allows pass argument for `Time#prev_day` and `Time#next_day`.
498
+ *Francesco Rodríguez*
438
499
 
439
- Before:
440
- ```
441
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
442
- Time.new(2017, 9, 16, 17, 0).prev_day(1)
443
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
500
+ * Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.
444
501
 
445
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
446
- Time.new(2017, 9, 16, 17, 0).next_day(1)
447
- # => ArgumentError: wrong number of arguments (given 1, expected 0)
448
- ```
502
+ *Francesco Rodríguez*
449
503
 
450
- After:
504
+ * Fix duration being rounded to a full second.
451
505
  ```
452
- Time.new(2017, 9, 16, 17, 0).prev_day # => 2017-09-15 17:00:00 +0300
453
- Time.new(2017, 9, 16, 17, 0).prev_day(1) # => 2017-09-15 17:00:00 +0300
454
-
455
- Time.new(2017, 9, 16, 17, 0).next_day # => 2017-09-17 17:00:00 +0300
456
- Time.new(2017, 9, 16, 17, 0).next_day(1) # => 2017-09-17 17:00:00 +0300
506
+ time = DateTime.parse("2018-1-1")
507
+ time += 0.51.seconds
457
508
  ```
509
+ Will now correctly add 0.51 second and not 1 full second.
458
510
 
459
- *bogdanvlviv*
511
+ *Edouard Chin*
460
512
 
461
- * `IO#to_json` now returns the `to_s` representation, rather than
462
- attempting to convert to an array. This fixes a bug where `IO#to_json`
463
- would raise an `IOError` when called on an unreadable object.
513
+ * Deprecate `ActiveSupport::Multibyte::Unicode#normalize` and `ActiveSupport::Multibyte::Chars#normalize`
514
+ in favor of `String#unicode_normalize`
464
515
 
465
- Fixes #26132.
516
+ *Francesco Rodríguez*
466
517
 
467
- *Paul Kuruvilla*
518
+ * Deprecate `ActiveSupport::Multibyte::Unicode#downcase/upcase/swapcase` in favor of
519
+ `String#downcase/upcase/swapcase`.
468
520
 
469
- * Remove deprecated `halt_callback_chains_on_return_false` option.
521
+ *Francesco Rodríguez*
470
522
 
471
- *Rafael Mendonça França*
523
+ * Add `ActiveSupport::ParameterFilter`.
472
524
 
473
- * Remove deprecated `:if` and `:unless` string filter for callbacks.
525
+ *Yoshiyuki Kinjo*
474
526
 
475
- *Rafael Mendonça França*
527
+ * Rename `Module#parent`, `Module#parents`, and `Module#parent_name` to
528
+ `module_parent`, `module_parents`, and `module_parent_name`.
476
529
 
477
- * `Hash#slice` now falls back to Ruby 2.5+'s built-in definition if defined.
530
+ *Gannon McGibbon*
478
531
 
479
- *Akira Matsuda*
532
+ * Deprecate the use of `LoggerSilence` in favor of `ActiveSupport::LoggerSilence`
480
533
 
481
- * Deprecate `secrets.secret_token`.
534
+ *Edouard Chin*
482
535
 
483
- The architecture for secrets had a big upgrade between Rails 3 and Rails 4,
484
- when the default changed from using `secret_token` to `secret_key_base`.
536
+ * Deprecate using negative limits in `String#first` and `String#last`.
485
537
 
486
- `secret_token` has been soft deprecated in documentation for four years
487
- but is still in place to support apps created before Rails 4.
488
- Deprecation warnings have been added to help developers upgrade their
489
- applications to `secret_key_base`.
538
+ *Gannon McGibbon*, *Eric Turner*
490
539
 
491
- *claudiob*, *Kasper Timm Hansen*
540
+ * Fix bug where `#without` for `ActiveSupport::HashWithIndifferentAccess` would fail
541
+ with symbol arguments
492
542
 
493
- * Return an instance of `HashWithIndifferentAccess` from `HashWithIndifferentAccess#transform_keys`.
543
+ *Abraham Chan*
494
544
 
495
- *Yuji Yaginuma*
545
+ * Treat `#delete_prefix`, `#delete_suffix` and `#unicode_normalize` results as non-`html_safe`.
546
+ Ensure safety of arguments for `#insert`, `#[]=` and `#replace` calls on `html_safe` Strings.
496
547
 
497
- * Add key rotation support to `MessageEncryptor` and `MessageVerifier`.
548
+ *Janosch Müller*
498
549
 
499
- This change introduces a `rotate` method to both the `MessageEncryptor` and
500
- `MessageVerifier` classes. This method accepts the same arguments and
501
- options as the given classes' constructor. The `encrypt_and_verify` method
502
- for `MessageEncryptor` and the `verified` method for `MessageVerifier` also
503
- accept an optional keyword argument `:on_rotation` block which is called
504
- when a rotated instance is used to decrypt or verify the message.
550
+ * Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
551
+ of mutating the one received as parameter.
505
552
 
506
- *Michael J Coyne*
553
+ *Thierry Joyal*
507
554
 
508
- * Deprecate `Module#reachable?` method.
555
+ * Define `unfreeze_time` as an alias of `travel_back` in `ActiveSupport::Testing::TimeHelpers`.
509
556
 
510
- *bogdanvlviv*
557
+ The alias is provided for symmetry with `freeze_time`.
511
558
 
512
- * Add `config/credentials.yml.enc` to store production app secrets.
559
+ *Ryan Davidson*
513
560
 
514
- Allows saving any authentication credentials for third party services
515
- directly in repo encrypted with `config/master.key` or `ENV["RAILS_MASTER_KEY"]`.
561
+ * Add support for tracing constant autoloads. Just throw
516
562
 
517
- This will eventually replace `Rails.application.secrets` and the encrypted
518
- secrets introduced in Rails 5.1.
563
+ ActiveSupport::Dependencies.logger = Rails.logger
564
+ ActiveSupport::Dependencies.verbose = true
519
565
 
520
- *DHH*, *Kasper Timm Hansen*
566
+ in an initializer.
521
567
 
522
- * Add `ActiveSupport::EncryptedFile` and `ActiveSupport::EncryptedConfiguration`.
568
+ *Xavier Noria*
523
569
 
524
- Allows for stashing encrypted files or configuration directly in repo by
525
- encrypting it with a key.
570
+ * Maintain `html_safe?` on html_safe strings when sliced.
526
571
 
527
- Backs the new credentials setup above, but can also be used independently.
572
+ string = "<div>test</div>".html_safe
573
+ string[-1..1].html_safe? # => true
528
574
 
529
- *DHH*, *Kasper Timm Hansen*
575
+ *Elom Gomez*, *Yumin Wong*
530
576
 
531
- * `Module#delegate_missing_to` now raises `DelegationError` if target is nil,
532
- similar to `Module#delegate`.
577
+ * Add `Array#extract!`.
533
578
 
534
- *Anton Khamets*
579
+ The method removes and returns the elements for which the block returns a true value.
580
+ If no block is given, an Enumerator is returned instead.
535
581
 
536
- * Update `String#camelize` to provide feedback when wrong option is passed.
582
+ numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
583
+ odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
584
+ numbers # => [0, 2, 4, 6, 8]
537
585
 
538
- `String#camelize` was returning nil without any feedback when an
539
- invalid option was passed as a parameter.
540
-
541
- Previously:
542
-
543
- 'one_two'.camelize(true)
544
- # => nil
545
-
546
- Now:
547
-
548
- 'one_two'.camelize(true)
549
- # => ArgumentError: Invalid option, use either :upper or :lower.
550
-
551
- *Ricardo Díaz*
552
-
553
- * Fix modulo operations involving durations.
554
-
555
- Rails 5.1 introduced `ActiveSupport::Duration::Scalar` as a wrapper
556
- around numeric values as a way of ensuring a duration was the outcome of
557
- an expression. However, the implementation was missing support for modulo
558
- operations. This support has now been added and should result in a duration
559
- being returned from expressions involving modulo operations.
586
+ *bogdanvlviv*
560
587
 
561
- Prior to Rails 5.1:
588
+ * Support not to cache `nil` for `ActiveSupport::Cache#fetch`.
562
589
 
563
- 5.minutes % 2.minutes
564
- # => 60
590
+ cache.fetch('bar', skip_nil: true) { nil }
591
+ cache.exist?('bar') # => false
565
592
 
566
- Now:
593
+ *Martin Hong*
567
594
 
568
- 5.minutes % 2.minutes
569
- # => 1 minute
595
+ * Add "event object" support to the notification system.
596
+ Before this change, end users were forced to create hand made artisanal
597
+ event objects on their own, like this:
570
598
 
571
- Fixes #29603 and #29743.
599
+ ActiveSupport::Notifications.subscribe('wait') do |*args|
600
+ @event = ActiveSupport::Notifications::Event.new(*args)
601
+ end
572
602
 
573
- *Sayan Chakraborty*, *Andrew White*
603
+ ActiveSupport::Notifications.instrument('wait') do
604
+ sleep 1
605
+ end
574
606
 
575
- * Fix division where a duration is the denominator.
607
+ @event.duration # => 1000.138
576
608
 
577
- PR #29163 introduced a change in behavior when a duration was the denominator
578
- in a calculation - this was incorrect as dividing by a duration should always
579
- return a `Numeric`. The behavior of previous versions of Rails has been restored.
609
+ After this change, if the block passed to `subscribe` only takes one
610
+ parameter, the framework will yield an event object to the block. Now
611
+ end users are no longer required to make their own:
580
612
 
581
- Fixes #29592.
613
+ ActiveSupport::Notifications.subscribe('wait') do |event|
614
+ @event = event
615
+ end
582
616
 
583
- *Andrew White*
617
+ ActiveSupport::Notifications.instrument('wait') do
618
+ sleep 1
619
+ end
584
620
 
585
- * Add purpose and expiry support to `ActiveSupport::MessageVerifier` and
586
- `ActiveSupport::MessageEncryptor`.
621
+ p @event.allocations # => 7
622
+ p @event.cpu_time # => 0.256
623
+ p @event.idle_time # => 1003.2399
587
624
 
588
- For instance, to ensure a message is only usable for one intended purpose:
625
+ Now you can enjoy event objects without making them yourself. Neat!
589
626
 
590
- token = @verifier.generate("x", purpose: :shipping)
627
+ *Aaron "t.lo" Patterson*
591
628
 
592
- @verifier.verified(token, purpose: :shipping) # => "x"
593
- @verifier.verified(token) # => nil
629
+ * Add cpu_time, idle_time, and allocations to Event.
594
630
 
595
- Or make it expire after a set time:
631
+ *Eileen M. Uchitelle*, *Aaron Patterson*
596
632
 
597
- @verifier.generate("x", expires_in: 1.month)
598
- @verifier.generate("y", expires_at: Time.now.end_of_year)
633
+ * RedisCacheStore: support key expiry in increment/decrement.
599
634
 
600
- Showcased with `ActiveSupport::MessageVerifier`, but works the same for
601
- `ActiveSupport::MessageEncryptor`'s `encrypt_and_sign` and `decrypt_and_verify`.
635
+ Pass `:expires_in` to `#increment` and `#decrement` to set a Redis EXPIRE on the key.
602
636
 
603
- Pull requests: #29599, #29854
637
+ If the key is already set to expire, RedisCacheStore won't extend its expiry.
604
638
 
605
- *Assain Jaleel*
639
+ Rails.cache.increment("some_key", 1, expires_in: 2.minutes)
606
640
 
607
- * Make the order of `Hash#reverse_merge!` consistent with `HashWithIndifferentAccess`.
641
+ *Jason Lee*
608
642
 
609
- *Erol Fornoles*
643
+ * Allow `Range#===` and `Range#cover?` on Range.
610
644
 
611
- * Add `freeze_time` helper which freezes time to `Time.now` in tests.
645
+ `Range#cover?` can now accept a range argument like `Range#include?` and
646
+ `Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
647
+ into a new file, with these two methods.
612
648
 
613
- *Prathamesh Sonpatki*
649
+ *Requiring active_support/core_ext/range/include_range is now deprecated.*
650
+ *Use `require "active_support/core_ext/range/compare_range"` instead.*
614
651
 
615
- * Default `ActiveSupport::MessageEncryptor` to use AES 256 GCM encryption.
652
+ *utilum*
616
653
 
617
- On for new Rails 5.2 apps. Upgrading apps can find the config as a new
618
- framework default.
654
+ * Add `index_with` to Enumerable.
619
655
 
620
- *Assain Jaleel*
656
+ Allows creating a hash from an enumerable with the value from a passed block
657
+ or a default argument.
621
658
 
622
- * Cache: `write_multi`.
659
+ %i( title body ).index_with { |attr| post.public_send(attr) }
660
+ # => { title: "hey", body: "what's up?" }
623
661
 
624
- Rails.cache.write_multi foo: 'bar', baz: 'qux'
662
+ %i( title body ).index_with(nil)
663
+ # => { title: nil, body: nil }
625
664
 
626
- Plus faster fetch_multi with stores that implement `write_multi_entries`.
627
- Keys that aren't found may be written to the cache store in one shot
628
- instead of separate writes.
665
+ Closely linked with `index_by`, which creates a hash where the keys are extracted from a block.
629
666
 
630
- The default implementation simply calls `write_entry` for each entry.
631
- Stores may override if they're capable of one-shot bulk writes, like
632
- Redis `MSET`.
667
+ *Kasper Timm Hansen*
633
668
 
634
- *Jeremy Daer*
669
+ * Fix bug where `ActiveSupport::TimeZone.all` would fail when tzinfo data for
670
+ any timezone defined in `ActiveSupport::TimeZone::MAPPING` is missing.
635
671
 
636
- * Add default option to module and class attribute accessors.
672
+ *Dominik Sander*
637
673
 
638
- mattr_accessor :settings, default: {}
674
+ * Redis cache store: `delete_matched` no longer blocks the Redis server.
675
+ (Switches from evaled Lua to a batched SCAN + DEL loop.)
639
676
 
640
- Works for `mattr_reader`, `mattr_writer`, `cattr_accessor`, `cattr_reader`,
641
- and `cattr_writer` as well.
677
+ *Gleb Mazovetskiy*
642
678
 
643
- *Genadi Samokovarov*
679
+ * Fix bug where `ActiveSupport::Cache` will massively inflate the storage
680
+ size when compression is enabled (which is true by default). This patch
681
+ does not attempt to repair existing data: please manually flush the cache
682
+ to clear out the problematic entries.
644
683
 
645
- * Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
684
+ *Godfrey Chan*
646
685
 
647
- *Shota Iguchi*
686
+ * Fix bug where `URI.unescape` would fail with mixed Unicode/escaped character input:
648
687
 
649
- * Add default option to `class_attribute`.
688
+ URI.unescape("\xe3\x83\x90") # => "バ"
689
+ URI.unescape("%E3%83%90") # => "バ"
690
+ URI.unescape("\xe3\x83\x90%E3%83%90") # => Encoding::CompatibilityError
650
691
 
651
- Before:
692
+ *Ashe Connor*, *Aaron Patterson*
652
693
 
653
- class_attribute :settings
654
- self.settings = {}
694
+ * Add `before?` and `after?` methods to `Date`, `DateTime`,
695
+ `Time`, and `TimeWithZone`.
655
696
 
656
- Now:
697
+ *Nick Holden*
657
698
 
658
- class_attribute :settings, default: {}
699
+ * `ActiveSupport::Inflector#ordinal` and `ActiveSupport::Inflector#ordinalize` now support
700
+ translations through I18n.
659
701
 
660
- *DHH*
702
+ # locale/fr.rb
661
703
 
662
- * `#singularize` and `#pluralize` now respect uncountables for the specified locale.
704
+ {
705
+ fr: {
706
+ number: {
707
+ nth: {
708
+ ordinals: lambda do |_key, number:, **_options|
709
+ if number.to_i.abs == 1
710
+ 'er'
711
+ else
712
+ 'e'
713
+ end
714
+ end,
663
715
 
664
- *Eilis Hamilton*
716
+ ordinalized: lambda do |_key, number:, **_options|
717
+ "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
718
+ end
719
+ }
720
+ }
721
+ }
722
+ }
665
723
 
666
- * Add `ActiveSupport::CurrentAttributes` to provide a thread-isolated attributes singleton.
667
- Primary use case is keeping all the per-request attributes easily available to the whole system.
668
724
 
669
- *DHH*
725
+ *Christian Blais*
670
726
 
671
- * Fix implicit coercion calculations with scalars and durations.
727
+ * Add `:private` option to ActiveSupport's `Module#delegate`
728
+ in order to delegate methods as private:
672
729
 
673
- Previously, calculations where the scalar is first would be converted to a duration
674
- of seconds, but this causes issues with dates being converted to times, e.g:
730
+ class User < ActiveRecord::Base
731
+ has_one :profile
732
+ delegate :date_of_birth, to: :profile, private: true
675
733
 
676
- Time.zone = "Beijing" # => Asia/Shanghai
677
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
678
- 2 * 1.day # => 172800 seconds
679
- date + 2 * 1.day # => Mon, 22 May 2017 00:00:00 CST +08:00
734
+ def age
735
+ Date.today.year - date_of_birth.year
736
+ end
737
+ end
680
738
 
681
- Now, the `ActiveSupport::Duration::Scalar` calculation methods will try to maintain
682
- the part structure of the duration where possible, e.g:
739
+ # User.new.age # => 29
740
+ # User.new.date_of_birth
741
+ # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
683
742
 
684
- Time.zone = "Beijing" # => Asia/Shanghai
685
- date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017
686
- 2 * 1.day # => 2 days
687
- date + 2 * 1.day # => Mon, 22 May 2017
743
+ *Tomas Valent*
688
744
 
689
- Fixes #29160, #28970.
745
+ * `String#truncate_bytes` to truncate a string to a maximum bytesize without
746
+ breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.
690
747
 
691
- *Andrew White*
748
+ *Jeremy Daer*
692
749
 
693
- * Add support for versioned cache entries. This enables the cache stores to recycle cache keys, greatly saving
694
- on storage in cases with frequent churn. Works together with the separation of `#cache_key` and `#cache_version`
695
- in Active Record and its use in Action Pack's fragment caching.
750
+ * `String#strip_heredoc` preserves frozenness.
696
751
 
697
- *DHH*
752
+ "foo".freeze.strip_heredoc.frozen? # => true
698
753
 
699
- * Pass gem name and deprecation horizon to deprecation notifications.
754
+ Fixes that frozen string literals would inadvertently become unfrozen:
700
755
 
701
- *Willem van Bergen*
756
+ # frozen_string_literal: true
702
757
 
703
- * Add support for `:offset` and `:zone` to `ActiveSupport::TimeWithZone#change`.
758
+ foo = <<-MSG.strip_heredoc
759
+ la la la
760
+ MSG
704
761
 
705
- *Andrew White*
762
+ foo.frozen? # => false !??
706
763
 
707
- * Add support for `:offset` to `Time#change`.
764
+ *Jeremy Daer*
708
765
 
709
- Fixes #28723.
766
+ * Rails 6 requires Ruby 2.5.0 or newer.
710
767
 
711
- *Andrew White*
768
+ *Jeremy Daer*, *Kasper Timm Hansen*
712
769
 
713
- * Add `fetch_values` for `HashWithIndifferentAccess`.
770
+ * Adds parallel testing to Rails.
714
771
 
715
- The method was originally added to `Hash` in Ruby 2.3.0.
772
+ Parallelize your test suite with forked processes or threads.
716
773
 
717
- *Josh Pencheon*
774
+ *Eileen M. Uchitelle*, *Aaron Patterson*
718
775
 
719
776
 
720
- Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activesupport/CHANGELOG.md) for previous changes.
777
+ Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activesupport/CHANGELOG.md) for previous changes.