activesupport 5.2.4.4 → 6.0.0

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

Potentially problematic release.


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

Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +327 -408
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -2
  5. data/lib/active_support.rb +2 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +28 -1
  8. data/lib/active_support/cache.rb +45 -23
  9. data/lib/active_support/cache/file_store.rb +22 -22
  10. data/lib/active_support/cache/mem_cache_store.rb +17 -2
  11. data/lib/active_support/cache/memory_store.rb +7 -2
  12. data/lib/active_support/cache/null_store.rb +5 -0
  13. data/lib/active_support/cache/redis_cache_store.rb +47 -25
  14. data/lib/active_support/callbacks.rb +16 -5
  15. data/lib/active_support/concern.rb +24 -1
  16. data/lib/active_support/configurable.rb +7 -11
  17. data/lib/active_support/core_ext/array.rb +1 -1
  18. data/lib/active_support/core_ext/array/access.rb +18 -6
  19. data/lib/active_support/core_ext/array/extract.rb +21 -0
  20. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  21. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  22. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  23. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  24. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  25. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  26. data/lib/active_support/core_ext/enumerable.rb +97 -73
  27. data/lib/active_support/core_ext/hash.rb +1 -2
  28. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  29. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  30. data/lib/active_support/core_ext/hash/except.rb +1 -1
  31. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  32. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  33. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  34. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  35. data/lib/active_support/core_ext/kernel.rb +0 -1
  36. data/lib/active_support/core_ext/load_error.rb +1 -1
  37. data/lib/active_support/core_ext/module.rb +0 -1
  38. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  39. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  40. data/lib/active_support/core_ext/module/delegation.rb +33 -7
  41. data/lib/active_support/core_ext/module/introspection.rb +37 -13
  42. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  43. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  44. data/lib/active_support/core_ext/numeric.rb +0 -1
  45. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  46. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  47. data/lib/active_support/core_ext/object/blank.rb +1 -2
  48. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  49. data/lib/active_support/core_ext/object/json.rb +1 -0
  50. data/lib/active_support/core_ext/object/try.rb +15 -7
  51. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  52. data/lib/active_support/core_ext/range/compare_range.rb +22 -13
  53. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  54. data/lib/active_support/core_ext/range/include_range.rb +6 -0
  55. data/lib/active_support/core_ext/regexp.rb +0 -4
  56. data/lib/active_support/core_ext/securerandom.rb +23 -3
  57. data/lib/active_support/core_ext/string/access.rb +8 -0
  58. data/lib/active_support/core_ext/string/filters.rb +42 -1
  59. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  60. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  61. data/lib/active_support/core_ext/string/output_safety.rb +61 -5
  62. data/lib/active_support/core_ext/string/strip.rb +3 -1
  63. data/lib/active_support/core_ext/time/calculations.rb +31 -2
  64. data/lib/active_support/core_ext/uri.rb +1 -0
  65. data/lib/active_support/current_attributes.rb +8 -0
  66. data/lib/active_support/dependencies.rb +69 -16
  67. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  68. data/lib/active_support/deprecation.rb +1 -1
  69. data/lib/active_support/deprecation/behaviors.rb +1 -1
  70. data/lib/active_support/deprecation/method_wrappers.rb +8 -20
  71. data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
  72. data/lib/active_support/descendants_tracker.rb +56 -9
  73. data/lib/active_support/duration.rb +4 -3
  74. data/lib/active_support/duration/iso8601_parser.rb +2 -3
  75. data/lib/active_support/duration/iso8601_serializer.rb +3 -4
  76. data/lib/active_support/encrypted_configuration.rb +0 -4
  77. data/lib/active_support/encrypted_file.rb +2 -1
  78. data/lib/active_support/evented_file_update_checker.rb +39 -9
  79. data/lib/active_support/execution_wrapper.rb +1 -0
  80. data/lib/active_support/gem_version.rb +4 -4
  81. data/lib/active_support/hash_with_indifferent_access.rb +22 -18
  82. data/lib/active_support/i18n.rb +1 -0
  83. data/lib/active_support/i18n_railtie.rb +9 -1
  84. data/lib/active_support/inflector/inflections.rb +1 -4
  85. data/lib/active_support/inflector/methods.rb +15 -27
  86. data/lib/active_support/inflector/transliterate.rb +47 -18
  87. data/lib/active_support/json/decoding.rb +23 -23
  88. data/lib/active_support/json/encoding.rb +6 -2
  89. data/lib/active_support/key_generator.rb +0 -32
  90. data/lib/active_support/lazy_load_hooks.rb +5 -1
  91. data/lib/active_support/locale/en.rb +31 -0
  92. data/lib/active_support/log_subscriber.rb +31 -8
  93. data/lib/active_support/logger.rb +0 -15
  94. data/lib/active_support/logger_silence.rb +28 -12
  95. data/lib/active_support/logger_thread_safe_level.rb +26 -4
  96. data/lib/active_support/message_encryptor.rb +3 -5
  97. data/lib/active_support/message_verifier.rb +3 -3
  98. data/lib/active_support/multibyte/chars.rb +29 -48
  99. data/lib/active_support/multibyte/unicode.rb +44 -281
  100. data/lib/active_support/notifications.rb +41 -4
  101. data/lib/active_support/notifications/fanout.rb +98 -13
  102. data/lib/active_support/notifications/instrumenter.rb +79 -8
  103. data/lib/active_support/number_helper.rb +7 -0
  104. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
  105. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
  106. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
  107. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
  108. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  109. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
  110. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
  111. data/lib/active_support/ordered_options.rb +1 -1
  112. data/lib/active_support/parameter_filter.rb +129 -0
  113. data/lib/active_support/rails.rb +0 -6
  114. data/lib/active_support/reloader.rb +4 -5
  115. data/lib/active_support/security_utils.rb +1 -1
  116. data/lib/active_support/subscriber.rb +65 -26
  117. data/lib/active_support/tagged_logging.rb +13 -4
  118. data/lib/active_support/test_case.rb +91 -0
  119. data/lib/active_support/testing/assertions.rb +15 -1
  120. data/lib/active_support/testing/deprecation.rb +0 -1
  121. data/lib/active_support/testing/file_fixtures.rb +2 -0
  122. data/lib/active_support/testing/isolation.rb +2 -2
  123. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  124. data/lib/active_support/testing/parallelization.rb +128 -0
  125. data/lib/active_support/testing/stream.rb +1 -1
  126. data/lib/active_support/testing/time_helpers.rb +7 -7
  127. data/lib/active_support/time_with_zone.rb +15 -5
  128. data/lib/active_support/values/time_zone.rb +12 -7
  129. data/lib/active_support/xml_mini.rb +2 -9
  130. data/lib/active_support/xml_mini/jdom.rb +2 -2
  131. data/lib/active_support/xml_mini/libxml.rb +2 -2
  132. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  133. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  134. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  135. data/lib/active_support/xml_mini/rexml.rb +2 -2
  136. metadata +34 -9
  137. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  138. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -3,7 +3,7 @@
3
3
  class Class
4
4
  begin
5
5
  # Test if this Ruby supports each_object against singleton_class
6
- ObjectSpace.each_object(Numeric.singleton_class) {}
6
+ ObjectSpace.each_object(Numeric.singleton_class) { }
7
7
 
8
8
  # Returns an array with all classes that are < than its receiver.
9
9
  #
@@ -110,12 +110,13 @@ class Date
110
110
  # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
111
111
  # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
112
112
  def advance(options)
113
- options = options.dup
114
113
  d = self
115
- d = d >> options.delete(:years) * 12 if options[:years]
116
- d = d >> options.delete(:months) if options[:months]
117
- d = d + options.delete(:weeks) * 7 if options[:weeks]
118
- d = d + options.delete(:days) if options[:days]
114
+
115
+ d = d >> options[:years] * 12 if options[:years]
116
+ d = d >> options[:months] if options[:months]
117
+ d = d + options[:weeks] * 7 if options[:weeks]
118
+ d = d + options[:days] if options[:days]
119
+
119
120
  d
120
121
  end
121
122
 
@@ -5,13 +5,13 @@ require "active_support/core_ext/object/try"
5
5
  module DateAndTime
6
6
  module Calculations
7
7
  DAYS_INTO_WEEK = {
8
- monday: 0,
9
- tuesday: 1,
10
- wednesday: 2,
11
- thursday: 3,
12
- friday: 4,
13
- saturday: 5,
14
- sunday: 6
8
+ sunday: 0,
9
+ monday: 1,
10
+ tuesday: 2,
11
+ wednesday: 3,
12
+ thursday: 4,
13
+ friday: 5,
14
+ saturday: 6
15
15
  }
16
16
  WEEKEND_DAYS = [ 6, 0 ]
17
17
 
@@ -20,21 +20,11 @@ module DateAndTime
20
20
  advance(days: -1)
21
21
  end
22
22
 
23
- # Returns a new date/time the specified number of days ago.
24
- def prev_day(days = 1)
25
- advance(days: -days)
26
- end
27
-
28
23
  # Returns a new date/time representing tomorrow.
29
24
  def tomorrow
30
25
  advance(days: 1)
31
26
  end
32
27
 
33
- # Returns a new date/time the specified number of days in the future.
34
- def next_day(days = 1)
35
- advance(days: days)
36
- end
37
-
38
28
  # Returns true if the date/time is today.
39
29
  def today?
40
30
  to_date == ::Date.current
@@ -60,6 +50,16 @@ module DateAndTime
60
50
  !WEEKEND_DAYS.include?(wday)
61
51
  end
62
52
 
53
+ # Returns true if the date/time falls before <tt>date_or_time</tt>.
54
+ def before?(date_or_time)
55
+ self < date_or_time
56
+ end
57
+
58
+ # Returns true if the date/time falls after <tt>date_or_time</tt>.
59
+ def after?(date_or_time)
60
+ self > date_or_time
61
+ end
62
+
63
63
  # Returns a new date/time the specified number of days ago.
64
64
  def days_ago(days)
65
65
  advance(days: -days)
@@ -124,7 +124,7 @@ module DateAndTime
124
124
  # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
125
125
  # now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
126
126
  def beginning_of_quarter
127
- first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
127
+ first_quarter_month = month - (2 + month) % 3
128
128
  beginning_of_month.change(month: first_quarter_month)
129
129
  end
130
130
  alias :at_beginning_of_quarter :beginning_of_quarter
@@ -139,7 +139,7 @@ module DateAndTime
139
139
  # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
140
140
  # now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
141
141
  def end_of_quarter
142
- last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
142
+ last_quarter_month = month + (12 - month) % 3
143
143
  beginning_of_month.change(month: last_quarter_month).end_of_month
144
144
  end
145
145
  alias :at_end_of_quarter :end_of_quarter
@@ -188,21 +188,11 @@ module DateAndTime
188
188
  end
189
189
  end
190
190
 
191
- # Returns a new date/time the specified number of months in the future.
192
- def next_month(months = 1)
193
- advance(months: months)
194
- end
195
-
196
191
  # Short-hand for months_since(3)
197
192
  def next_quarter
198
193
  months_since(3)
199
194
  end
200
195
 
201
- # Returns a new date/time the specified number of years in the future.
202
- def next_year(years = 1)
203
- advance(years: years)
204
- end
205
-
206
196
  # Returns a new date/time representing the given day in the previous week.
207
197
  # Week is assumed to start on +start_day+, default is
208
198
  # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
@@ -223,11 +213,6 @@ module DateAndTime
223
213
  end
224
214
  alias_method :last_weekday, :prev_weekday
225
215
 
226
- # Returns a new date/time the specified number of months ago.
227
- def prev_month(months = 1)
228
- advance(months: -months)
229
- end
230
-
231
216
  # Short-hand for months_ago(1).
232
217
  def last_month
233
218
  months_ago(1)
@@ -239,11 +224,6 @@ module DateAndTime
239
224
  end
240
225
  alias_method :last_quarter, :prev_quarter
241
226
 
242
- # Returns a new date/time the specified number of years ago.
243
- def prev_year(years = 1)
244
- advance(years: -years)
245
- end
246
-
247
227
  # Short-hand for years_ago(1).
248
228
  def last_year
249
229
  years_ago(1)
@@ -253,9 +233,8 @@ module DateAndTime
253
233
  # Week is assumed to start on +start_day+, default is
254
234
  # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
255
235
  def days_to_week_start(start_day = Date.beginning_of_week)
256
- start_day_number = DAYS_INTO_WEEK[start_day]
257
- current_day_number = wday != 0 ? wday - 1 : 6
258
- (current_day_number - start_day_number) % 7
236
+ start_day_number = DAYS_INTO_WEEK.fetch(start_day)
237
+ (wday - start_day_number) % 7
259
238
  end
260
239
 
261
240
  # Returns a new date/time representing the start of this week on the given day.
@@ -336,8 +315,7 @@ module DateAndTime
336
315
  # today.next_occurring(:monday) # => Mon, 18 Dec 2017
337
316
  # today.next_occurring(:thursday) # => Thu, 21 Dec 2017
338
317
  def next_occurring(day_of_week)
339
- current_day_number = wday != 0 ? wday - 1 : 6
340
- from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
318
+ from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday
341
319
  from_now += 7 unless from_now > 0
342
320
  advance(days: from_now)
343
321
  end
@@ -348,8 +326,7 @@ module DateAndTime
348
326
  # today.prev_occurring(:monday) # => Mon, 11 Dec 2017
349
327
  # today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
350
328
  def prev_occurring(day_of_week)
351
- current_day_number = wday != 0 ? wday - 1 : 6
352
- ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
329
+ ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
353
330
  ago += 7 unless ago > 0
354
331
  advance(days: -ago)
355
332
  end
@@ -364,7 +341,7 @@ module DateAndTime
364
341
  end
365
342
 
366
343
  def days_span(day)
367
- (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
344
+ (DAYS_INTO_WEEK.fetch(day) - DAYS_INTO_WEEK.fetch(Date.beginning_of_week)) % 7
368
345
  end
369
346
 
370
347
  def copy_time_to(other)
@@ -110,7 +110,7 @@ class DateTime
110
110
  # instance time. Do not use this method in combination with x.months, use
111
111
  # months_since instead!
112
112
  def since(seconds)
113
- self + Rational(seconds.round, 86400)
113
+ self + Rational(seconds, 86400)
114
114
  end
115
115
  alias :in :since
116
116
 
@@ -1,64 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Enumerable
4
+ INDEX_WITH_DEFAULT = Object.new
5
+ private_constant :INDEX_WITH_DEFAULT
6
+
4
7
  # Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
5
8
  # when we omit an identity.
9
+
10
+ # :stopdoc:
11
+
12
+ # We can't use Refinements here because Refinements with Module which will be prepended
13
+ # doesn't work well https://bugs.ruby-lang.org/issues/13446
14
+ alias :_original_sum_with_required_identity :sum
15
+ private :_original_sum_with_required_identity
16
+
17
+ # :startdoc:
18
+
19
+ # Calculates a sum from the elements.
6
20
  #
7
- # We tried shimming it to attempt the fast native method, rescue TypeError,
8
- # and fall back to the compatible implementation, but that's much slower than
9
- # just calling the compat method in the first place.
10
- if Enumerable.instance_methods(false).include?(:sum) && !((?a..?b).sum rescue false)
11
- # :stopdoc:
12
-
13
- # We can't use Refinements here because Refinements with Module which will be prepended
14
- # doesn't work well https://bugs.ruby-lang.org/issues/13446
15
- alias :_original_sum_with_required_identity :sum
16
- private :_original_sum_with_required_identity
17
-
18
- # :startdoc:
19
-
20
- # Calculates a sum from the elements.
21
- #
22
- # payments.sum { |p| p.price * p.tax_rate }
23
- # payments.sum(&:price)
24
- #
25
- # The latter is a shortcut for:
26
- #
27
- # payments.inject(0) { |sum, p| sum + p.price }
28
- #
29
- # It can also calculate the sum without the use of a block.
30
- #
31
- # [5, 15, 10].sum # => 30
32
- # ['foo', 'bar'].sum # => "foobar"
33
- # [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
34
- #
35
- # The default sum of an empty list is zero. You can override this default:
36
- #
37
- # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
38
- def sum(identity = nil, &block)
39
- if identity
40
- _original_sum_with_required_identity(identity, &block)
41
- elsif block_given?
42
- map(&block).sum(identity)
43
- else
44
- inject(:+) || 0
45
- end
46
- end
47
- else
48
- def sum(identity = nil, &block)
49
- if block_given?
50
- map(&block).sum(identity)
51
- else
52
- sum = identity ? inject(identity, :+) : inject(:+)
53
- sum || identity || 0
54
- end
21
+ # payments.sum { |p| p.price * p.tax_rate }
22
+ # payments.sum(&:price)
23
+ #
24
+ # The latter is a shortcut for:
25
+ #
26
+ # payments.inject(0) { |sum, p| sum + p.price }
27
+ #
28
+ # It can also calculate the sum without the use of a block.
29
+ #
30
+ # [5, 15, 10].sum # => 30
31
+ # ['foo', 'bar'].sum # => "foobar"
32
+ # [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
33
+ #
34
+ # The default sum of an empty list is zero. You can override this default:
35
+ #
36
+ # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
37
+ def sum(identity = nil, &block)
38
+ if identity
39
+ _original_sum_with_required_identity(identity, &block)
40
+ elsif block_given?
41
+ map(&block).sum(identity)
42
+ else
43
+ inject(:+) || 0
55
44
  end
56
45
  end
57
46
 
58
- # Convert an enumerable to a hash.
47
+ # Convert an enumerable to a hash keying it by the block return value.
59
48
  #
60
49
  # people.index_by(&:login)
61
50
  # # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
51
+ #
62
52
  # people.index_by { |person| "#{person.first_name} #{person.last_name}" }
63
53
  # # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
64
54
  def index_by
@@ -71,6 +61,26 @@ module Enumerable
71
61
  end
72
62
  end
73
63
 
64
+ # Convert an enumerable to a hash keying it with the enumerable items and with the values returned in the block.
65
+ #
66
+ # post = Post.new(title: "hey there", body: "what's up?")
67
+ #
68
+ # %i( title body ).index_with { |attr_name| post.public_send(attr_name) }
69
+ # # => { title: "hey there", body: "what's up?" }
70
+ def index_with(default = INDEX_WITH_DEFAULT)
71
+ if block_given?
72
+ result = {}
73
+ each { |elem| result[elem] = yield(elem) }
74
+ result
75
+ elsif default != INDEX_WITH_DEFAULT
76
+ result = {}
77
+ each { |elem| result[elem] = default }
78
+ result
79
+ else
80
+ to_enum(:index_with) { size if respond_to?(:size) }
81
+ end
82
+ end
83
+
74
84
  # Returns +true+ if the enumerable has more than 1 element. Functionally
75
85
  # equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
76
86
  # much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
@@ -87,23 +97,43 @@ module Enumerable
87
97
  end
88
98
  end
89
99
 
100
+ # Returns a new array that includes the passed elements.
101
+ #
102
+ # [ 1, 2, 3 ].including(4, 5)
103
+ # # => [ 1, 2, 3, 4, 5 ]
104
+ #
105
+ # ["David", "Rafael"].including %w[ Aaron Todd ]
106
+ # # => ["David", "Rafael", "Aaron", "Todd"]
107
+ def including(*elements)
108
+ to_a.including(*elements)
109
+ end
110
+
90
111
  # The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
91
112
  # collection does not include the object.
92
113
  def exclude?(object)
93
114
  !include?(object)
94
115
  end
95
116
 
96
- # Returns a copy of the enumerable without the specified elements.
117
+ # Returns a copy of the enumerable excluding the specified elements.
118
+ #
119
+ # ["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd"
120
+ # # => ["David", "Rafael"]
97
121
  #
98
- # ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
122
+ # ["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ]
99
123
  # # => ["David", "Rafael"]
100
124
  #
101
- # {foo: 1, bar: 2, baz: 3}.without :bar
125
+ # {foo: 1, bar: 2, baz: 3}.excluding :bar
102
126
  # # => {foo: 1, baz: 3}
103
- def without(*elements)
127
+ def excluding(*elements)
128
+ elements.flatten!(1)
104
129
  reject { |element| elements.include?(element) }
105
130
  end
106
131
 
132
+ # Alias for #excluding.
133
+ def without(*elements)
134
+ excluding(*elements)
135
+ end
136
+
107
137
  # Convert an enumerable to an array based on the given key.
108
138
  #
109
139
  # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
@@ -138,27 +168,21 @@ class Range #:nodoc:
138
168
  end
139
169
  end
140
170
 
141
- # Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
142
- #
143
- # We tried shimming it to attempt the fast native method, rescue TypeError,
144
- # and fall back to the compatible implementation, but that's much slower than
145
- # just calling the compat method in the first place.
146
- if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
147
- # Using Refinements here in order not to expose our internal method
148
- using Module.new {
149
- refine Array do
150
- alias :orig_sum :sum
151
- end
152
- }
171
+ # Using Refinements here in order not to expose our internal method
172
+ using Module.new {
173
+ refine Array do
174
+ alias :orig_sum :sum
175
+ end
176
+ }
153
177
 
154
- class Array
155
- def sum(init = nil, &block) #:nodoc:
156
- if init.is_a?(Numeric) || first.is_a?(Numeric)
157
- init ||= 0
158
- orig_sum(init, &block)
159
- else
160
- super
161
- end
178
+ class Array #:nodoc:
179
+ # Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
180
+ def sum(init = nil, &block)
181
+ if init.is_a?(Numeric) || first.is_a?(Numeric)
182
+ init ||= 0
183
+ orig_sum(init, &block)
184
+ else
185
+ super
162
186
  end
163
187
  end
164
188
  end
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/hash/compact"
4
3
  require "active_support/core_ext/hash/conversions"
5
4
  require "active_support/core_ext/hash/deep_merge"
5
+ require "active_support/core_ext/hash/deep_transform_values"
6
6
  require "active_support/core_ext/hash/except"
7
7
  require "active_support/core_ext/hash/indifferent_access"
8
8
  require "active_support/core_ext/hash/keys"
9
9
  require "active_support/core_ext/hash/reverse_merge"
10
10
  require "active_support/core_ext/hash/slice"
11
- require "active_support/core_ext/hash/transform_values"
@@ -1,29 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Hash
4
- unless Hash.instance_methods(false).include?(:compact)
5
- # Returns a hash with non +nil+ values.
6
- #
7
- # hash = { a: true, b: false, c: nil }
8
- # hash.compact # => { a: true, b: false }
9
- # hash # => { a: true, b: false, c: nil }
10
- # { c: nil }.compact # => {}
11
- # { c: true }.compact # => { c: true }
12
- def compact
13
- select { |_, value| !value.nil? }
14
- end
15
- end
3
+ require "active_support/deprecation"
16
4
 
17
- unless Hash.instance_methods(false).include?(:compact!)
18
- # Replaces current hash with non +nil+ values.
19
- # Returns +nil+ if no changes were made, otherwise returns the hash.
20
- #
21
- # hash = { a: true, b: false, c: nil }
22
- # hash.compact! # => { a: true, b: false }
23
- # hash # => { a: true, b: false }
24
- # { c: true }.compact! # => nil
25
- def compact!
26
- reject! { |_, value| value.nil? }
27
- end
28
- end
29
- end
5
+ ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Hash#compact and Hash#compact! natively, so requiring active_support/core_ext/hash/compact is no longer necessary. Requiring it will raise LoadError in Rails 6.1."