activesupport 5.2.1.1 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +416 -351
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -2
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +28 -1
- data/lib/active_support/cache.rb +45 -23
- data/lib/active_support/cache/file_store.rb +22 -22
- data/lib/active_support/cache/mem_cache_store.rb +5 -0
- data/lib/active_support/cache/memory_store.rb +9 -2
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +37 -10
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/concern.rb +31 -4
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +97 -73
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +33 -7
- data/lib/active_support/core_ext/module/introspection.rb +37 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/try.rb +15 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/include_range.rb +6 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +63 -5
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +2 -1
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +74 -17
- data/lib/active_support/dependencies/zeitwerk_integration.rb +118 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +13 -12
- data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
- data/lib/active_support/descendants_tracker.rb +56 -9
- data/lib/active_support/duration.rb +6 -5
- data/lib/active_support/duration/iso8601_parser.rb +2 -3
- data/lib/active_support/duration/iso8601_serializer.rb +3 -4
- data/lib/active_support/encrypted_configuration.rb +1 -5
- data/lib/active_support/encrypted_file.rb +2 -1
- data/lib/active_support/evented_file_update_checker.rb +39 -9
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +36 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +14 -2
- data/lib/active_support/inflector/inflections.rb +1 -4
- data/lib/active_support/inflector/methods.rb +17 -27
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -23
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -1
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/log_subscriber.rb +31 -8
- data/lib/active_support/logger.rb +0 -15
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +28 -5
- data/lib/active_support/message_encryptor.rb +3 -5
- data/lib/active_support/message_verifier.rb +3 -3
- data/lib/active_support/multibyte/chars.rb +29 -48
- data/lib/active_support/multibyte/unicode.rb +44 -281
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +100 -15
- data/lib/active_support/notifications/instrumenter.rb +80 -8
- data/lib/active_support/number_helper.rb +7 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +129 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +65 -22
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +7 -7
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +12 -7
- data/lib/active_support/xml_mini.rb +2 -9
- data/lib/active_support/xml_mini/jdom.rb +2 -2
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- metadata +33 -10
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- 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
|
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
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
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"].
|
122
|
+
# ["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ]
|
99
123
|
# # => ["David", "Rafael"]
|
100
124
|
#
|
101
|
-
# {foo: 1, bar: 2, baz: 3}.
|
125
|
+
# {foo: 1, bar: 2, baz: 3}.excluding :bar
|
102
126
|
# # => {foo: 1, baz: 3}
|
103
|
-
def
|
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
|
-
#
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
@@ -29,7 +29,7 @@ class File
|
|
29
29
|
old_stat = if exist?(file_name)
|
30
30
|
# Get original file permissions
|
31
31
|
stat(file_name)
|
32
|
-
|
32
|
+
else
|
33
33
|
# If not possible, probe which are the default permissions in the
|
34
34
|
# destination directory.
|
35
35
|
probe_stat_in(dirname(file_name))
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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 }
|
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
|
-
|
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
|
-
|
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."
|