activesupport 5.2.3.rc1 → 6.0.0.beta1
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 +183 -469
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support.rb +1 -1
- data/lib/active_support/backtrace_cleaner.rb +23 -0
- data/lib/active_support/cache.rb +40 -18
- data/lib/active_support/cache/file_store.rb +19 -12
- data/lib/active_support/cache/mem_cache_store.rb +5 -0
- data/lib/active_support/cache/memory_store.rb +5 -0
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +28 -4
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/configurable.rb +4 -8
- data/lib/active_support/core_ext/array.rb +1 -1
- 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 +1 -1
- 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 -17
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +71 -67
- data/lib/active_support/core_ext/hash.rb +0 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- 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/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 +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -14
- data/lib/active_support/core_ext/module/delegation.rb +27 -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 +5 -2
- 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/compare_range.rb +1 -1
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/include_range.rb +6 -0
- 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 +41 -0
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +16 -5
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/uri.rb +1 -0
- data/lib/active_support/current_attributes.rb +2 -0
- data/lib/active_support/dependencies.rb +28 -11
- 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 +4 -5
- data/lib/active_support/deprecation/proxy_wrappers.rb +0 -2
- data/lib/active_support/descendants_tracker.rb +6 -5
- data/lib/active_support/duration.rb +4 -2
- 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 +0 -4
- data/lib/active_support/evented_file_update_checker.rb +25 -7
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +16 -28
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +8 -1
- data/lib/active_support/inflector/inflections.rb +1 -4
- data/lib/active_support/inflector/methods.rb +15 -27
- data/lib/active_support/inflector/transliterate.rb +6 -6
- 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 +26 -4
- data/lib/active_support/message_encryptor.rb +2 -4
- data/lib/active_support/message_verifier.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +29 -48
- data/lib/active_support/multibyte/unicode.rb +44 -281
- data/lib/active_support/notifications.rb +32 -4
- data/lib/active_support/notifications/fanout.rb +40 -2
- data/lib/active_support/notifications/instrumenter.rb +73 -2
- 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/parameter_filter.rb +124 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/subscriber.rb +16 -26
- 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 +109 -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 +9 -6
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Array
|
4
|
+
# Removes and returns the elements for which the block returns a true value.
|
5
|
+
# If no block is given, an Enumerator is returned instead.
|
6
|
+
#
|
7
|
+
# numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
8
|
+
# odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
|
9
|
+
# numbers # => [0, 2, 4, 6, 8]
|
10
|
+
def extract!
|
11
|
+
return to_enum(:extract!) { size } unless block_given?
|
12
|
+
|
13
|
+
extracted_elements = []
|
14
|
+
|
15
|
+
reject! do |element|
|
16
|
+
extracted_elements << element if yield(element)
|
17
|
+
end
|
18
|
+
|
19
|
+
extracted_elements
|
20
|
+
end
|
21
|
+
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# The human way of thinking about adding stuff to the end of a list is with append.
|
5
|
-
alias_method :append, :push unless [].respond_to?(:append)
|
3
|
+
require "active_support/deprecation"
|
6
4
|
|
7
|
-
|
8
|
-
alias_method :prepend, :unshift unless [].respond_to?(:prepend)
|
9
|
-
end
|
5
|
+
ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Array#append and Array#prepend natively, so requiring active_support/core_ext/array/prepend_and_append is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
|
@@ -98,7 +98,7 @@ class Class
|
|
98
98
|
singleton_class.silence_redefinition_of_method("#{name}?")
|
99
99
|
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
100
100
|
|
101
|
-
ivar = "@#{name}"
|
101
|
+
ivar = "@#{name}".to_sym
|
102
102
|
|
103
103
|
singleton_class.silence_redefinition_of_method("#{name}=")
|
104
104
|
define_singleton_method("#{name}=") do |val|
|
@@ -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
|
-
|
116
|
-
d = d >> options
|
117
|
-
d = d
|
118
|
-
d = d +
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
|
@@ -60,6 +60,16 @@ module DateAndTime
|
|
60
60
|
!WEEKEND_DAYS.include?(wday)
|
61
61
|
end
|
62
62
|
|
63
|
+
# Returns true if the date/time falls before <tt>date_or_time</tt>.
|
64
|
+
def before?(date_or_time)
|
65
|
+
self < date_or_time
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns true if the date/time falls after <tt>date_or_time</tt>.
|
69
|
+
def after?(date_or_time)
|
70
|
+
self > date_or_time
|
71
|
+
end
|
72
|
+
|
63
73
|
# Returns a new date/time the specified number of days ago.
|
64
74
|
def days_ago(days)
|
65
75
|
advance(days: -days)
|
@@ -124,7 +134,7 @@ module DateAndTime
|
|
124
134
|
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
125
135
|
# now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
|
126
136
|
def beginning_of_quarter
|
127
|
-
first_quarter_month =
|
137
|
+
first_quarter_month = month - (2 + month) % 3
|
128
138
|
beginning_of_month.change(month: first_quarter_month)
|
129
139
|
end
|
130
140
|
alias :at_beginning_of_quarter :beginning_of_quarter
|
@@ -139,7 +149,7 @@ module DateAndTime
|
|
139
149
|
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
140
150
|
# now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
|
141
151
|
def end_of_quarter
|
142
|
-
last_quarter_month =
|
152
|
+
last_quarter_month = month + (12 - month) % 3
|
143
153
|
beginning_of_month.change(month: last_quarter_month).end_of_month
|
144
154
|
end
|
145
155
|
alias :at_end_of_quarter :end_of_quarter
|
@@ -253,9 +263,8 @@ module DateAndTime
|
|
253
263
|
# Week is assumed to start on +start_day+, default is
|
254
264
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
255
265
|
def days_to_week_start(start_day = Date.beginning_of_week)
|
256
|
-
start_day_number = DAYS_INTO_WEEK
|
257
|
-
|
258
|
-
(current_day_number - start_day_number) % 7
|
266
|
+
start_day_number = DAYS_INTO_WEEK.fetch(start_day)
|
267
|
+
(wday - start_day_number) % 7
|
259
268
|
end
|
260
269
|
|
261
270
|
# Returns a new date/time representing the start of this week on the given day.
|
@@ -336,8 +345,7 @@ module DateAndTime
|
|
336
345
|
# today.next_occurring(:monday) # => Mon, 18 Dec 2017
|
337
346
|
# today.next_occurring(:thursday) # => Thu, 21 Dec 2017
|
338
347
|
def next_occurring(day_of_week)
|
339
|
-
|
340
|
-
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
|
348
|
+
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday
|
341
349
|
from_now += 7 unless from_now > 0
|
342
350
|
advance(days: from_now)
|
343
351
|
end
|
@@ -348,8 +356,7 @@ module DateAndTime
|
|
348
356
|
# today.prev_occurring(:monday) # => Mon, 11 Dec 2017
|
349
357
|
# today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
|
350
358
|
def prev_occurring(day_of_week)
|
351
|
-
|
352
|
-
ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
|
359
|
+
ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
|
353
360
|
ago += 7 unless ago > 0
|
354
361
|
advance(days: -ago)
|
355
362
|
end
|
@@ -364,7 +371,7 @@ module DateAndTime
|
|
364
371
|
end
|
365
372
|
|
366
373
|
def days_span(day)
|
367
|
-
(DAYS_INTO_WEEK
|
374
|
+
(DAYS_INTO_WEEK.fetch(day) - DAYS_INTO_WEEK.fetch(Date.beginning_of_week)) % 7
|
368
375
|
end
|
369
376
|
|
370
377
|
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
|
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.
|
6
|
-
#
|
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
9
|
|
13
|
-
|
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
|
10
|
+
# :stopdoc:
|
17
11
|
|
18
|
-
|
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
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
17
|
+
# :startdoc:
|
18
|
+
|
19
|
+
# Calculates a sum from the elements.
|
20
|
+
#
|
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+
|
@@ -138,27 +148,21 @@ class Range #:nodoc:
|
|
138
148
|
end
|
139
149
|
end
|
140
150
|
|
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
|
-
}
|
151
|
+
# Using Refinements here in order not to expose our internal method
|
152
|
+
using Module.new {
|
153
|
+
refine Array do
|
154
|
+
alias :orig_sum :sum
|
155
|
+
end
|
156
|
+
}
|
153
157
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
class Array #:nodoc:
|
159
|
+
# Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
|
160
|
+
def sum(init = nil, &block)
|
161
|
+
if init.is_a?(Numeric) || first.is_a?(Numeric)
|
162
|
+
init ||= 0
|
163
|
+
orig_sum(init, &block)
|
164
|
+
else
|
165
|
+
super
|
162
166
|
end
|
163
167
|
end
|
164
168
|
end
|
@@ -1,6 +1,5 @@
|
|
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"
|
6
5
|
require "active_support/core_ext/hash/except"
|
@@ -8,4 +7,3 @@ require "active_support/core_ext/hash/indifferent_access"
|
|
8
7
|
require "active_support/core_ext/hash/keys"
|
9
8
|
require "active_support/core_ext/hash/reverse_merge"
|
10
9
|
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."
|
@@ -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)
|