activesupport 5.2.4.2 → 6.0.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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +383 -397
  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 +5 -0
  11. data/lib/active_support/cache/memory_store.rb +9 -2
  12. data/lib/active_support/cache/null_store.rb +5 -0
  13. data/lib/active_support/cache/redis_cache_store.rb +37 -10
  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 +28 -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/range/include_time_with_zone.rb +2 -2
  56. data/lib/active_support/core_ext/regexp.rb +0 -4
  57. data/lib/active_support/core_ext/securerandom.rb +23 -3
  58. data/lib/active_support/core_ext/string/access.rb +8 -0
  59. data/lib/active_support/core_ext/string/filters.rb +42 -1
  60. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  61. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  62. data/lib/active_support/core_ext/string/output_safety.rb +63 -5
  63. data/lib/active_support/core_ext/string/strip.rb +3 -1
  64. data/lib/active_support/core_ext/time/calculations.rb +31 -2
  65. data/lib/active_support/core_ext/uri.rb +1 -0
  66. data/lib/active_support/current_attributes.rb +8 -0
  67. data/lib/active_support/dependencies.rb +69 -16
  68. data/lib/active_support/dependencies/zeitwerk_integration.rb +118 -0
  69. data/lib/active_support/deprecation.rb +1 -1
  70. data/lib/active_support/deprecation/behaviors.rb +1 -1
  71. data/lib/active_support/deprecation/method_wrappers.rb +8 -20
  72. data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
  73. data/lib/active_support/descendants_tracker.rb +56 -9
  74. data/lib/active_support/duration.rb +6 -5
  75. data/lib/active_support/duration/iso8601_parser.rb +2 -3
  76. data/lib/active_support/duration/iso8601_serializer.rb +3 -4
  77. data/lib/active_support/encrypted_configuration.rb +0 -4
  78. data/lib/active_support/encrypted_file.rb +2 -1
  79. data/lib/active_support/evented_file_update_checker.rb +39 -9
  80. data/lib/active_support/execution_wrapper.rb +1 -0
  81. data/lib/active_support/gem_version.rb +4 -4
  82. data/lib/active_support/hash_with_indifferent_access.rb +22 -18
  83. data/lib/active_support/i18n.rb +1 -0
  84. data/lib/active_support/i18n_railtie.rb +13 -1
  85. data/lib/active_support/inflector/inflections.rb +1 -4
  86. data/lib/active_support/inflector/methods.rb +15 -27
  87. data/lib/active_support/inflector/transliterate.rb +47 -18
  88. data/lib/active_support/json/decoding.rb +23 -23
  89. data/lib/active_support/json/encoding.rb +6 -2
  90. data/lib/active_support/key_generator.rb +0 -32
  91. data/lib/active_support/lazy_load_hooks.rb +5 -1
  92. data/lib/active_support/locale/en.rb +31 -0
  93. data/lib/active_support/log_subscriber.rb +31 -8
  94. data/lib/active_support/logger.rb +0 -15
  95. data/lib/active_support/logger_silence.rb +28 -12
  96. data/lib/active_support/logger_thread_safe_level.rb +26 -4
  97. data/lib/active_support/message_encryptor.rb +3 -5
  98. data/lib/active_support/message_verifier.rb +3 -3
  99. data/lib/active_support/multibyte/chars.rb +29 -48
  100. data/lib/active_support/multibyte/unicode.rb +44 -281
  101. data/lib/active_support/notifications.rb +41 -4
  102. data/lib/active_support/notifications/fanout.rb +98 -13
  103. data/lib/active_support/notifications/instrumenter.rb +80 -8
  104. data/lib/active_support/number_helper.rb +7 -0
  105. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
  106. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
  107. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
  108. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
  109. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  110. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
  111. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
  112. data/lib/active_support/ordered_hash.rb +1 -1
  113. data/lib/active_support/ordered_options.rb +1 -1
  114. data/lib/active_support/parameter_filter.rb +129 -0
  115. data/lib/active_support/rails.rb +0 -6
  116. data/lib/active_support/reloader.rb +4 -5
  117. data/lib/active_support/security_utils.rb +1 -1
  118. data/lib/active_support/subscriber.rb +65 -26
  119. data/lib/active_support/tagged_logging.rb +13 -4
  120. data/lib/active_support/test_case.rb +91 -0
  121. data/lib/active_support/testing/assertions.rb +15 -1
  122. data/lib/active_support/testing/deprecation.rb +0 -1
  123. data/lib/active_support/testing/file_fixtures.rb +2 -0
  124. data/lib/active_support/testing/isolation.rb +2 -2
  125. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  126. data/lib/active_support/testing/parallelization.rb +128 -0
  127. data/lib/active_support/testing/stream.rb +1 -1
  128. data/lib/active_support/testing/time_helpers.rb +7 -7
  129. data/lib/active_support/time_with_zone.rb +15 -5
  130. data/lib/active_support/values/time_zone.rb +12 -7
  131. data/lib/active_support/xml_mini.rb +2 -9
  132. data/lib/active_support/xml_mini/jdom.rb +2 -2
  133. data/lib/active_support/xml_mini/libxml.rb +2 -2
  134. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  135. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  136. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  137. data/lib/active_support/xml_mini/rexml.rb +2 -2
  138. metadata +30 -8
  139. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  140. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -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."
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ # Returns a new hash with all values converted by the block operation.
5
+ # This includes the values from the root hash and from all
6
+ # nested hashes and arrays.
7
+ #
8
+ # hash = { person: { name: 'Rob', age: '28' } }
9
+ #
10
+ # hash.deep_transform_values{ |value| value.to_s.upcase }
11
+ # # => {person: {name: "ROB", age: "28"}}
12
+ def deep_transform_values(&block)
13
+ _deep_transform_values_in_object(self, &block)
14
+ end
15
+
16
+ # Destructively converts all values by using the block operation.
17
+ # This includes the values from the root hash and from all
18
+ # nested hashes and arrays.
19
+ def deep_transform_values!(&block)
20
+ _deep_transform_values_in_object!(self, &block)
21
+ end
22
+
23
+ private
24
+ # support methods for deep transforming nested hashes and arrays
25
+ def _deep_transform_values_in_object(object, &block)
26
+ case object
27
+ when Hash
28
+ object.transform_values { |value| _deep_transform_values_in_object(value, &block) }
29
+ when Array
30
+ object.map { |e| _deep_transform_values_in_object(e, &block) }
31
+ else
32
+ yield(object)
33
+ end
34
+ end
35
+
36
+ def _deep_transform_values_in_object!(object, &block)
37
+ case object
38
+ when Hash
39
+ object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) }
40
+ when Array
41
+ object.map! { |e| _deep_transform_values_in_object!(e, &block) }
42
+ else
43
+ yield(object)
44
+ end
45
+ end
46
+ end
@@ -10,7 +10,7 @@ class Hash
10
10
  # This is useful for limiting a set of parameters to everything but a few known toggles:
11
11
  # @person.update(params[:person].except(:admin))
12
12
  def except(*keys)
13
- dup.except!(*keys)
13
+ slice(*self.keys - keys)
14
14
  end
15
15
 
16
16
  # Removes the given keys from hash and returns it.
@@ -1,35 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Hash
4
- # Returns a new hash with all keys converted using the +block+ operation.
5
- #
6
- # hash = { name: 'Rob', age: '28' }
7
- #
8
- # hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
9
- #
10
- # If you do not provide a +block+, it will return an Enumerator
11
- # for chaining with other methods:
12
- #
13
- # hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
14
- def transform_keys
15
- return enum_for(:transform_keys) { size } unless block_given?
16
- result = {}
17
- each_key do |key|
18
- result[yield(key)] = self[key]
19
- end
20
- result
21
- end unless method_defined? :transform_keys
22
-
23
- # Destructively converts all keys using the +block+ operations.
24
- # Same as +transform_keys+ but modifies +self+.
25
- def transform_keys!
26
- return enum_for(:transform_keys!) { size } unless block_given?
27
- keys.each do |key|
28
- self[yield(key)] = delete(key)
29
- end
30
- self
31
- end unless method_defined? :transform_keys!
32
-
33
4
  # Returns a new hash with all keys converted to strings.
34
5
  #
35
6
  # hash = { name: 'Rob', age: '28' }
@@ -1,34 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Hash
4
- # Slices a hash to include only the given keys. Returns a hash containing
5
- # the given keys.
6
- #
7
- # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
8
- # # => {:a=>1, :b=>2}
9
- #
10
- # This is useful for limiting an options hash to valid keys before
11
- # passing to a method:
12
- #
13
- # def search(criteria = {})
14
- # criteria.assert_valid_keys(:mass, :velocity, :time)
15
- # end
16
- #
17
- # search(options.slice(:mass, :velocity, :time))
18
- #
19
- # If you have an array of keys you want to limit to, you should splat them:
20
- #
21
- # valid_keys = [:mass, :velocity, :time]
22
- # search(options.slice(*valid_keys))
23
- def slice(*keys)
24
- keys.each_with_object(Hash.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
25
- end unless method_defined?(:slice)
26
-
27
4
  # Replaces the hash with only the given keys.
28
5
  # Returns a hash containing the removed key/value pairs.
29
6
  #
30
- # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
31
- # # => {:c=>3, :d=>4}
7
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
8
+ # hash.slice!(:a, :b) # => {:c=>3, :d=>4}
9
+ # hash # => {:a=>1, :b=>2}
32
10
  def slice!(*keys)
33
11
  omit = slice(*self.keys - keys)
34
12
  hash = slice(*keys)
@@ -1,32 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Hash
4
- # Returns a new hash with the results of running +block+ once for every value.
5
- # The keys are unchanged.
6
- #
7
- # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } # => { a: 2, b: 4, c: 6 }
8
- #
9
- # If you do not provide a +block+, it will return an Enumerator
10
- # for chaining with other methods:
11
- #
12
- # { a: 1, b: 2 }.transform_values.with_index { |v, i| [v, i].join.to_i } # => { a: 10, b: 21 }
13
- def transform_values
14
- return enum_for(:transform_values) { size } unless block_given?
15
- return {} if empty?
16
- result = self.class.new
17
- each do |key, value|
18
- result[key] = yield(value)
19
- end
20
- result
21
- end unless method_defined? :transform_values
3
+ require "active_support/deprecation"
22
4
 
23
- # Destructively converts all values using the +block+ operations.
24
- # Same as +transform_values+ but modifies +self+.
25
- def transform_values!
26
- return enum_for(:transform_values!) { size } unless block_given?
27
- each do |key, value|
28
- self[key] = yield(value)
29
- end
30
- end unless method_defined? :transform_values!
31
- # TODO: Remove this file when supporting only Ruby 2.4+.
32
- end
5
+ ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Hash#transform_values natively, so requiring active_support/core_ext/hash/transform_values is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
@@ -7,6 +7,6 @@ class Integer
7
7
  # 6.multiple_of?(5) # => false
8
8
  # 10.multiple_of?(2) # => true
9
9
  def multiple_of?(number)
10
- number != 0 ? self % number == 0 : zero?
10
+ number == 0 ? self == 0 : self % number == 0
11
11
  end
12
12
  end