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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +327 -408
- 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 +17 -2
- data/lib/active_support/cache/memory_store.rb +7 -2
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +47 -25
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/concern.rb +24 -1
- 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/enumerable.rb +97 -73
- 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/compare_range.rb +22 -13
- 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 +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 +61 -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 +1 -0
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +69 -16
- data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -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 +8 -20
- 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 +4 -3
- 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/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 +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +22 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +9 -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 +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 +26 -4
- 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 +98 -13
- data/lib/active_support/notifications/instrumenter.rb +79 -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_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 -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 +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 +34 -9
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -30,6 +30,11 @@ module ActiveSupport
|
|
30
30
|
@pruning = false
|
31
31
|
end
|
32
32
|
|
33
|
+
# Advertise cache versioning support.
|
34
|
+
def self.supports_cache_versioning?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
33
38
|
# Delete all data stored in a given cache store.
|
34
39
|
def clear(options = nil)
|
35
40
|
synchronize do
|
@@ -57,13 +62,13 @@ module ActiveSupport
|
|
57
62
|
return if pruning?
|
58
63
|
@pruning = true
|
59
64
|
begin
|
60
|
-
start_time =
|
65
|
+
start_time = Concurrent.monotonic_time
|
61
66
|
cleanup
|
62
67
|
instrument(:prune, target_size, from: @cache_size) do
|
63
68
|
keys = synchronize { @key_access.keys.sort { |a, b| @key_access[a].to_f <=> @key_access[b].to_f } }
|
64
69
|
keys.each do |key|
|
65
70
|
delete_entry(key, options)
|
66
|
-
return if @cache_size <= target_size || (max_time &&
|
71
|
+
return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
|
67
72
|
end
|
68
73
|
end
|
69
74
|
ensure
|
@@ -17,7 +17,6 @@ end
|
|
17
17
|
|
18
18
|
require "digest/sha2"
|
19
19
|
require "active_support/core_ext/marshal"
|
20
|
-
require "active_support/core_ext/hash/transform_values"
|
21
20
|
|
22
21
|
module ActiveSupport
|
23
22
|
module Cache
|
@@ -67,9 +66,22 @@ module ActiveSupport
|
|
67
66
|
SCAN_BATCH_SIZE = 1000
|
68
67
|
private_constant :SCAN_BATCH_SIZE
|
69
68
|
|
69
|
+
# Advertise cache versioning support.
|
70
|
+
def self.supports_cache_versioning?
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
70
74
|
# Support raw values in the local cache strategy.
|
71
75
|
module LocalCacheWithRaw # :nodoc:
|
72
76
|
private
|
77
|
+
def read_entry(key, options)
|
78
|
+
entry = super
|
79
|
+
if options[:raw] && local_cache && entry
|
80
|
+
entry = deserialize_entry(entry.value)
|
81
|
+
end
|
82
|
+
entry
|
83
|
+
end
|
84
|
+
|
73
85
|
def write_entry(key, entry, options)
|
74
86
|
if options[:raw] && local_cache
|
75
87
|
raw_entry = Entry.new(serialize_entry(entry, raw: true))
|
@@ -140,15 +152,17 @@ module ActiveSupport
|
|
140
152
|
|
141
153
|
# Creates a new Redis cache store.
|
142
154
|
#
|
143
|
-
# Handles
|
144
|
-
#
|
155
|
+
# Handles four options: :redis block, :redis instance, single :url
|
156
|
+
# string, and multiple :url strings.
|
145
157
|
#
|
146
|
-
#
|
147
|
-
# :
|
148
|
-
# :
|
158
|
+
# Option Class Result
|
159
|
+
# :redis Proc -> options[:redis].call
|
160
|
+
# :redis Object -> options[:redis]
|
161
|
+
# :url String -> Redis.new(url: …)
|
162
|
+
# :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …])
|
149
163
|
#
|
150
164
|
# No namespace is set by default. Provide one if the Redis cache
|
151
|
-
# server is shared with other apps: <tt>namespace: 'myapp-cache'
|
165
|
+
# server is shared with other apps: <tt>namespace: 'myapp-cache'</tt>.
|
152
166
|
#
|
153
167
|
# Compression is enabled by default with a 1kB threshold, so cached
|
154
168
|
# values larger than 1kB are automatically compressed. Disable by
|
@@ -251,7 +265,14 @@ module ActiveSupport
|
|
251
265
|
def increment(name, amount = 1, options = nil)
|
252
266
|
instrument :increment, name, amount: amount do
|
253
267
|
failsafe :increment do
|
254
|
-
|
268
|
+
options = merged_options(options)
|
269
|
+
key = normalize_key(name, options)
|
270
|
+
|
271
|
+
redis.with do |c|
|
272
|
+
c.incrby(key, amount).tap do
|
273
|
+
write_key_expiry(c, key, options)
|
274
|
+
end
|
275
|
+
end
|
255
276
|
end
|
256
277
|
end
|
257
278
|
end
|
@@ -267,7 +288,14 @@ module ActiveSupport
|
|
267
288
|
def decrement(name, amount = 1, options = nil)
|
268
289
|
instrument :decrement, name, amount: amount do
|
269
290
|
failsafe :decrement do
|
270
|
-
|
291
|
+
options = merged_options(options)
|
292
|
+
key = normalize_key(name, options)
|
293
|
+
|
294
|
+
redis.with do |c|
|
295
|
+
c.decrby(key, amount).tap do
|
296
|
+
write_key_expiry(c, key, options)
|
297
|
+
end
|
298
|
+
end
|
271
299
|
end
|
272
300
|
end
|
273
301
|
end
|
@@ -320,8 +348,7 @@ module ActiveSupport
|
|
320
348
|
# Read an entry from the cache.
|
321
349
|
def read_entry(key, options = nil)
|
322
350
|
failsafe :read_entry do
|
323
|
-
|
324
|
-
deserialize_entry(redis.with { |c| c.get(key) }, raw: raw)
|
351
|
+
deserialize_entry redis.with { |c| c.get(key) }
|
325
352
|
end
|
326
353
|
end
|
327
354
|
|
@@ -336,7 +363,7 @@ module ActiveSupport
|
|
336
363
|
def read_multi_mget(*names)
|
337
364
|
options = names.extract_options!
|
338
365
|
options = merged_options(options)
|
339
|
-
|
366
|
+
return {} if names == []
|
340
367
|
|
341
368
|
keys = names.map { |name| normalize_key(name, options) }
|
342
369
|
|
@@ -346,7 +373,7 @@ module ActiveSupport
|
|
346
373
|
|
347
374
|
names.zip(values).each_with_object({}) do |(name, value), results|
|
348
375
|
if value
|
349
|
-
entry = deserialize_entry(value
|
376
|
+
entry = deserialize_entry(value)
|
350
377
|
unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(name, options))
|
351
378
|
results[name] = entry.value
|
352
379
|
end
|
@@ -380,6 +407,12 @@ module ActiveSupport
|
|
380
407
|
end
|
381
408
|
end
|
382
409
|
|
410
|
+
def write_key_expiry(client, key, options)
|
411
|
+
if options[:expires_in] && client.ttl(key).negative?
|
412
|
+
client.expire key, options[:expires_in].to_i
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
383
416
|
# Delete an entry from the cache.
|
384
417
|
def delete_entry(key, options)
|
385
418
|
failsafe :delete_entry, returning: false do
|
@@ -415,20 +448,9 @@ module ActiveSupport
|
|
415
448
|
end
|
416
449
|
end
|
417
450
|
|
418
|
-
def deserialize_entry(serialized_entry
|
451
|
+
def deserialize_entry(serialized_entry)
|
419
452
|
if serialized_entry
|
420
453
|
entry = Marshal.load(serialized_entry) rescue serialized_entry
|
421
|
-
|
422
|
-
written_raw = serialized_entry.equal?(entry)
|
423
|
-
if raw != written_raw
|
424
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
425
|
-
Using a different value for the raw option when reading and writing
|
426
|
-
to a cache key is deprecated for :redis_cache_store and Rails 6.0
|
427
|
-
will stop automatically detecting the format when reading to avoid
|
428
|
-
marshal loading untrusted raw strings.
|
429
|
-
MSG
|
430
|
-
end
|
431
|
-
|
432
454
|
entry.is_a?(Entry) ? entry : Entry.new(entry)
|
433
455
|
end
|
434
456
|
end
|
@@ -23,6 +23,9 @@ module ActiveSupport
|
|
23
23
|
# +ClassMethods.set_callback+), and run the installed callbacks at the
|
24
24
|
# appropriate times (via +run_callbacks+).
|
25
25
|
#
|
26
|
+
# By default callbacks are halted by throwing +:abort+.
|
27
|
+
# See +ClassMethods.define_callbacks+ for details.
|
28
|
+
#
|
26
29
|
# Three kinds of callbacks are supported: before callbacks, run before a
|
27
30
|
# certain event; after callbacks, run after the event; and around callbacks,
|
28
31
|
# blocks that surround the event, triggering it when they yield. Callback code
|
@@ -497,9 +500,7 @@ module ActiveSupport
|
|
497
500
|
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
|
498
501
|
end
|
499
502
|
|
500
|
-
|
501
|
-
@nested
|
502
|
-
end
|
503
|
+
attr_reader :nested
|
503
504
|
|
504
505
|
def final?
|
505
506
|
!@call_template
|
@@ -578,7 +579,7 @@ module ActiveSupport
|
|
578
579
|
end
|
579
580
|
|
580
581
|
protected
|
581
|
-
|
582
|
+
attr_reader :chain
|
582
583
|
|
583
584
|
private
|
584
585
|
|
@@ -659,9 +660,17 @@ module ActiveSupport
|
|
659
660
|
# * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance
|
660
661
|
# method or a proc; the callback will be called only when they all return
|
661
662
|
# a true value.
|
663
|
+
#
|
664
|
+
# If a proc is given, its body is evaluated in the context of the
|
665
|
+
# current object. It can also optionally accept the current object as
|
666
|
+
# an argument.
|
662
667
|
# * <tt>:unless</tt> - A symbol or an array of symbols, each naming an
|
663
668
|
# instance method or a proc; the callback will be called only when they
|
664
669
|
# all return a false value.
|
670
|
+
#
|
671
|
+
# If a proc is given, its body is evaluated in the context of the
|
672
|
+
# current object. It can also optionally accept the current object as
|
673
|
+
# an argument.
|
665
674
|
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
|
666
675
|
# existing chain rather than appended.
|
667
676
|
def set_callback(name, *filter_list, &block)
|
@@ -809,7 +818,9 @@ module ActiveSupport
|
|
809
818
|
names.each do |name|
|
810
819
|
name = name.to_sym
|
811
820
|
|
812
|
-
|
821
|
+
([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
|
822
|
+
target.set_callbacks name, CallbackChain.new(name, options)
|
823
|
+
end
|
813
824
|
|
814
825
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
815
826
|
def _run_#{name}_callbacks(&block)
|
@@ -110,7 +110,7 @@ module ActiveSupport
|
|
110
110
|
base.instance_variable_set(:@_dependencies, [])
|
111
111
|
end
|
112
112
|
|
113
|
-
def append_features(base)
|
113
|
+
def append_features(base) #:nodoc:
|
114
114
|
if base.instance_variable_defined?(:@_dependencies)
|
115
115
|
base.instance_variable_get(:@_dependencies) << self
|
116
116
|
false
|
@@ -123,6 +123,9 @@ module ActiveSupport
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
# Evaluate given block in context of base class,
|
127
|
+
# so that you can write class macros here.
|
128
|
+
# When you define more than one +included+ block, it raises an exception.
|
126
129
|
def included(base = nil, &block)
|
127
130
|
if base.nil?
|
128
131
|
if instance_variable_defined?(:@_included_block)
|
@@ -137,6 +140,26 @@ module ActiveSupport
|
|
137
140
|
end
|
138
141
|
end
|
139
142
|
|
143
|
+
# Define class methods from given block.
|
144
|
+
# You can define private class methods as well.
|
145
|
+
#
|
146
|
+
# module Example
|
147
|
+
# extend ActiveSupport::Concern
|
148
|
+
#
|
149
|
+
# class_methods do
|
150
|
+
# def foo; puts 'foo'; end
|
151
|
+
#
|
152
|
+
# private
|
153
|
+
# def bar; puts 'bar'; end
|
154
|
+
# end
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# class Buzz
|
158
|
+
# include Example
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# Buzz.foo # => "foo"
|
162
|
+
# Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError)
|
140
163
|
def class_methods(&class_methods_module_definition)
|
141
164
|
mod = const_defined?(:ClassMethods, false) ?
|
142
165
|
const_get(:ClassMethods) :
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/concern"
|
4
4
|
require "active_support/ordered_options"
|
5
|
-
require "active_support/core_ext/array/extract_options"
|
6
|
-
require "active_support/core_ext/regexp"
|
7
5
|
|
8
6
|
module ActiveSupport
|
9
7
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
@@ -69,8 +67,8 @@ module ActiveSupport
|
|
69
67
|
# end
|
70
68
|
# # => NameError: invalid config attribute name
|
71
69
|
#
|
72
|
-
# To
|
73
|
-
# To
|
70
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
71
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
74
72
|
#
|
75
73
|
# class User
|
76
74
|
# include ActiveSupport::Configurable
|
@@ -83,7 +81,7 @@ module ActiveSupport
|
|
83
81
|
# User.new.allowed_access = true # => NoMethodError
|
84
82
|
# User.new.allowed_access # => NoMethodError
|
85
83
|
#
|
86
|
-
# Or pass <tt>instance_accessor: false</tt>, to
|
84
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
87
85
|
#
|
88
86
|
# class User
|
89
87
|
# include ActiveSupport::Configurable
|
@@ -106,9 +104,7 @@ module ActiveSupport
|
|
106
104
|
# end
|
107
105
|
#
|
108
106
|
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
109
|
-
def config_accessor(*names)
|
110
|
-
options = names.extract_options!
|
111
|
-
|
107
|
+
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
|
112
108
|
names.each do |name|
|
113
109
|
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
|
114
110
|
|
@@ -118,9 +114,9 @@ module ActiveSupport
|
|
118
114
|
singleton_class.class_eval reader, __FILE__, reader_line
|
119
115
|
singleton_class.class_eval writer, __FILE__, writer_line
|
120
116
|
|
121
|
-
|
122
|
-
class_eval reader, __FILE__, reader_line
|
123
|
-
class_eval writer, __FILE__, writer_line
|
117
|
+
if instance_accessor
|
118
|
+
class_eval reader, __FILE__, reader_line if instance_reader
|
119
|
+
class_eval writer, __FILE__, writer_line if instance_writer
|
124
120
|
end
|
125
121
|
send("#{name}=", yield) if block_given?
|
126
122
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "active_support/core_ext/array/wrap"
|
4
4
|
require "active_support/core_ext/array/access"
|
5
5
|
require "active_support/core_ext/array/conversions"
|
6
|
+
require "active_support/core_ext/array/extract"
|
6
7
|
require "active_support/core_ext/array/extract_options"
|
7
8
|
require "active_support/core_ext/array/grouping"
|
8
|
-
require "active_support/core_ext/array/prepend_and_append"
|
9
9
|
require "active_support/core_ext/array/inquiry"
|
@@ -29,16 +29,28 @@ class Array
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
# Returns a
|
32
|
+
# Returns a new array that includes the passed elements.
|
33
33
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
|
34
|
+
# [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
|
35
|
+
# [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
|
36
|
+
def including(*elements)
|
37
|
+
self + elements.flatten(1)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a copy of the Array excluding the specified elements.
|
41
|
+
#
|
42
|
+
# ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
|
43
|
+
# [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
|
37
44
|
#
|
38
|
-
# Note: This is an optimization of <tt>Enumerable#
|
45
|
+
# Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
|
39
46
|
# instead of <tt>Array#reject</tt> for performance reasons.
|
47
|
+
def excluding(*elements)
|
48
|
+
self - elements.flatten(1)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Alias for #excluding.
|
40
52
|
def without(*elements)
|
41
|
-
|
53
|
+
excluding(*elements)
|
42
54
|
end
|
43
55
|
|
44
56
|
# Equal to <tt>self[1]</tt>.
|
@@ -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."
|
@@ -84,27 +84,26 @@ class Class
|
|
84
84
|
# To set a default value for the attribute, pass <tt>default:</tt>, like so:
|
85
85
|
#
|
86
86
|
# class_attribute :settings, default: {}
|
87
|
-
def class_attribute(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
def class_attribute(
|
88
|
+
*attrs,
|
89
|
+
instance_accessor: true,
|
90
|
+
instance_reader: instance_accessor,
|
91
|
+
instance_writer: instance_accessor,
|
92
|
+
instance_predicate: true,
|
93
|
+
default: nil
|
94
|
+
)
|
94
95
|
attrs.each do |name|
|
95
96
|
singleton_class.silence_redefinition_of_method(name)
|
96
|
-
define_singleton_method(name) {
|
97
|
+
define_singleton_method(name) { default }
|
97
98
|
|
98
99
|
singleton_class.silence_redefinition_of_method("#{name}?")
|
99
100
|
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
100
101
|
|
101
|
-
ivar = "@#{name}"
|
102
|
+
ivar = "@#{name}".to_sym
|
102
103
|
|
103
104
|
singleton_class.silence_redefinition_of_method("#{name}=")
|
104
105
|
define_singleton_method("#{name}=") do |val|
|
105
|
-
|
106
|
-
redefine_method(name) { val }
|
107
|
-
end
|
106
|
+
redefine_singleton_method(name) { val }
|
108
107
|
|
109
108
|
if singleton_class?
|
110
109
|
class_eval do
|
@@ -137,10 +136,6 @@ class Class
|
|
137
136
|
instance_variable_set ivar, val
|
138
137
|
end
|
139
138
|
end
|
140
|
-
|
141
|
-
unless default_value.nil?
|
142
|
-
self.send("#{name}=", default_value)
|
143
|
-
end
|
144
139
|
end
|
145
140
|
end
|
146
141
|
end
|