activesupport 6.0.3.4 → 6.1.3
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 +371 -448
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support.rb +13 -1
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +3 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache.rb +85 -44
- data/lib/active_support/cache/file_store.rb +4 -3
- data/lib/active_support/cache/mem_cache_store.rb +29 -18
- data/lib/active_support/cache/memory_store.rb +46 -26
- data/lib/active_support/cache/redis_cache_store.rb +27 -27
- data/lib/active_support/cache/strategy/local_cache.rb +21 -6
- data/lib/active_support/callbacks.rb +65 -56
- data/lib/active_support/concern.rb +46 -2
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/enumerable.rb +76 -4
- data/lib/active_support/core_ext/hash/conversions.rb +2 -2
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +38 -28
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +13 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/range/compare_range.rb +9 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/inflections.rb +38 -4
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +10 -10
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/time/calculations.rb +27 -3
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +5 -1
- data/lib/active_support/current_attributes.rb +7 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/dependencies.rb +43 -19
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/deprecation/behaviors.rb +15 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -2
- data/lib/active_support/deprecation/proxy_wrappers.rb +3 -3
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/descendants_tracker.rb +6 -2
- data/lib/active_support/duration.rb +71 -22
- data/lib/active_support/duration/iso8601_serializer.rb +15 -9
- data/lib/active_support/encrypted_file.rb +19 -2
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +69 -133
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +43 -24
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +1 -2
- data/lib/active_support/inflector/methods.rb +35 -31
- data/lib/active_support/inflector/transliterate.rb +4 -4
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +5 -1
- data/lib/active_support/key_generator.rb +1 -1
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +8 -0
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -12
- data/lib/active_support/message_encryptor.rb +4 -7
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +9 -1
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +4 -42
- data/lib/active_support/multibyte/unicode.rb +9 -83
- data/lib/active_support/notifications.rb +32 -5
- data/lib/active_support/notifications/fanout.rb +23 -8
- data/lib/active_support/notifications/instrumenter.rb +6 -15
- data/lib/active_support/number_helper.rb +29 -14
- data/lib/active_support/number_helper/number_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -7
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +3 -3
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/option_merger.rb +3 -2
- data/lib/active_support/ordered_options.rb +8 -2
- data/lib/active_support/parameter_filter.rb +16 -11
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +12 -7
- data/lib/active_support/tagged_logging.rb +29 -4
- data/lib/active_support/testing/assertions.rb +18 -11
- data/lib/active_support/testing/parallelization.rb +12 -95
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/time_helpers.rb +40 -3
- data/lib/active_support/time_with_zone.rb +67 -43
- data/lib/active_support/values/time_zone.rb +20 -10
- data/lib/active_support/xml_mini/rexml.rb +8 -1
- metadata +34 -36
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/xml_mini"
|
4
|
-
require "active_support/time"
|
5
4
|
require "active_support/core_ext/object/blank"
|
6
5
|
require "active_support/core_ext/object/to_param"
|
7
6
|
require "active_support/core_ext/object/to_query"
|
7
|
+
require "active_support/core_ext/object/try"
|
8
8
|
require "active_support/core_ext/array/wrap"
|
9
9
|
require "active_support/core_ext/hash/reverse_merge"
|
10
10
|
require "active_support/core_ext/string/inflections"
|
@@ -208,7 +208,7 @@ module ActiveSupport
|
|
208
208
|
elsif become_empty_string?(value)
|
209
209
|
""
|
210
210
|
elsif become_hash?(value)
|
211
|
-
xml_value =
|
211
|
+
xml_value = value.transform_values { |v| deep_to_h(v) }
|
212
212
|
|
213
213
|
# Turn { files: { file: #<StringIO> } } into { files: #<StringIO> } so it is compatible with
|
214
214
|
# how multipart uploaded files from HTML appear
|
@@ -112,7 +112,7 @@ class Hash
|
|
112
112
|
end
|
113
113
|
|
114
114
|
private
|
115
|
-
#
|
115
|
+
# Support methods for deep transforming nested hashes and arrays.
|
116
116
|
def _deep_transform_keys_in_object(object, &block)
|
117
117
|
case object
|
118
118
|
when Hash
|
@@ -18,8 +18,9 @@ class Hash
|
|
18
18
|
|
19
19
|
# Removes and returns the key/value pairs matching the given keys.
|
20
20
|
#
|
21
|
-
# { a: 1, b: 2, c: 3, d: 4 }
|
22
|
-
#
|
21
|
+
# hash = { a: 1, b: 2, c: 3, d: 4 }
|
22
|
+
# hash.extract!(:a, :b) # => {:a=>1, :b=>2}
|
23
|
+
# hash # => {:c=>3, :d=>4}
|
23
24
|
def extract!(*keys)
|
24
25
|
keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
|
25
26
|
end
|
@@ -4,6 +4,6 @@ class LoadError
|
|
4
4
|
# Returns true if the given path name (except perhaps for the ".rb"
|
5
5
|
# extension) is the missing file which caused the exception to be raised.
|
6
6
|
def is_missing?(location)
|
7
|
-
location.
|
7
|
+
location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb")
|
8
8
|
end
|
9
9
|
end
|
@@ -28,9 +28,9 @@ class Module
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def attr_internal_define(attr_name, type)
|
31
|
-
internal_name = attr_internal_ivar_name(attr_name).
|
31
|
+
internal_name = attr_internal_ivar_name(attr_name).delete_prefix("@")
|
32
32
|
# use native attr_* methods as they are faster on some Ruby implementations
|
33
|
-
|
33
|
+
public_send("attr_#{type}", internal_name)
|
34
34
|
attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
|
35
35
|
alias_method attr_name, internal_name
|
36
36
|
remove_method internal_name
|
@@ -48,28 +48,25 @@ class Module
|
|
48
48
|
# end
|
49
49
|
#
|
50
50
|
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
51
|
-
def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil)
|
51
|
+
def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil)
|
52
|
+
raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
|
53
|
+
location ||= caller_locations(1, 1).first
|
54
|
+
|
55
|
+
definition = []
|
52
56
|
syms.each do |sym|
|
53
57
|
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
54
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
55
|
-
@@#{sym} = nil unless defined? @@#{sym}
|
56
58
|
|
57
|
-
|
58
|
-
@@#{sym}
|
59
|
-
end
|
60
|
-
EOS
|
59
|
+
definition << "def self.#{sym}; @@#{sym}; end"
|
61
60
|
|
62
61
|
if instance_reader && instance_accessor
|
63
|
-
|
64
|
-
def #{sym}
|
65
|
-
@@#{sym}
|
66
|
-
end
|
67
|
-
EOS
|
62
|
+
definition << "def #{sym}; @@#{sym}; end"
|
68
63
|
end
|
69
64
|
|
70
65
|
sym_default_value = (block_given? && default.nil?) ? yield : default
|
71
|
-
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil?
|
66
|
+
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
|
72
67
|
end
|
68
|
+
|
69
|
+
module_eval(definition.join(";"), location.path, location.lineno)
|
73
70
|
end
|
74
71
|
alias :cattr_reader :mattr_reader
|
75
72
|
|
@@ -115,28 +112,24 @@ class Module
|
|
115
112
|
# end
|
116
113
|
#
|
117
114
|
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
118
|
-
def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil)
|
115
|
+
def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil)
|
116
|
+
raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
|
117
|
+
location ||= caller_locations(1, 1).first
|
118
|
+
|
119
|
+
definition = []
|
119
120
|
syms.each do |sym|
|
120
121
|
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
121
|
-
|
122
|
-
@@#{sym} = nil unless defined? @@#{sym}
|
123
|
-
|
124
|
-
def self.#{sym}=(obj)
|
125
|
-
@@#{sym} = obj
|
126
|
-
end
|
127
|
-
EOS
|
122
|
+
definition << "def self.#{sym}=(val); @@#{sym} = val; end"
|
128
123
|
|
129
124
|
if instance_writer && instance_accessor
|
130
|
-
|
131
|
-
def #{sym}=(obj)
|
132
|
-
@@#{sym} = obj
|
133
|
-
end
|
134
|
-
EOS
|
125
|
+
definition << "def #{sym}=(val); @@#{sym} = val; end"
|
135
126
|
end
|
136
127
|
|
137
128
|
sym_default_value = (block_given? && default.nil?) ? yield : default
|
138
|
-
|
129
|
+
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
|
139
130
|
end
|
131
|
+
|
132
|
+
module_eval(definition.join(";"), location.path, location.lineno)
|
140
133
|
end
|
141
134
|
alias :cattr_writer :mattr_writer
|
142
135
|
|
@@ -205,8 +198,9 @@ class Module
|
|
205
198
|
#
|
206
199
|
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
207
200
|
def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
|
208
|
-
|
209
|
-
|
201
|
+
location = caller_locations(1, 1).first
|
202
|
+
mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk)
|
203
|
+
mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location)
|
210
204
|
end
|
211
205
|
alias :cattr_accessor :mattr_accessor
|
212
206
|
end
|
@@ -33,7 +33,7 @@ class Module
|
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
# Current.new.user # => NoMethodError
|
36
|
-
def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true) # :nodoc:
|
36
|
+
def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc:
|
37
37
|
syms.each do |sym|
|
38
38
|
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
|
39
39
|
|
@@ -52,6 +52,8 @@ class Module
|
|
52
52
|
end
|
53
53
|
EOS
|
54
54
|
end
|
55
|
+
|
56
|
+
Thread.current["attr_" + name + "_#{sym}"] = default unless default.nil?
|
55
57
|
end
|
56
58
|
end
|
57
59
|
alias :thread_cattr_reader :thread_mattr_reader
|
@@ -74,7 +76,7 @@ class Module
|
|
74
76
|
# end
|
75
77
|
#
|
76
78
|
# Current.new.user = "DHH" # => NoMethodError
|
77
|
-
def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true) # :nodoc:
|
79
|
+
def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) # :nodoc:
|
78
80
|
syms.each do |sym|
|
79
81
|
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
|
80
82
|
|
@@ -93,6 +95,8 @@ class Module
|
|
93
95
|
end
|
94
96
|
EOS
|
95
97
|
end
|
98
|
+
|
99
|
+
public_send("#{sym}=", default) unless default.nil?
|
96
100
|
end
|
97
101
|
end
|
98
102
|
alias :thread_cattr_writer :thread_mattr_writer
|
@@ -136,8 +140,8 @@ class Module
|
|
136
140
|
#
|
137
141
|
# Current.new.user = "DHH" # => NoMethodError
|
138
142
|
# Current.new.user # => NoMethodError
|
139
|
-
def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true)
|
140
|
-
thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor)
|
143
|
+
def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil)
|
144
|
+
thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default)
|
141
145
|
thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
|
142
146
|
end
|
143
147
|
alias :thread_cattr_accessor :thread_mattr_accessor
|
@@ -104,10 +104,16 @@ class Module
|
|
104
104
|
# * grok the behavior of our class in one glance,
|
105
105
|
# * clean up monolithic junk-drawer classes by separating their concerns, and
|
106
106
|
# * stop leaning on protected/private for crude "this is internal stuff" modularity.
|
107
|
+
#
|
108
|
+
# === Prepending concerning
|
109
|
+
#
|
110
|
+
# <tt>concerning</tt> supports a <tt>prepend: true</tt> argument which will <tt>prepend</tt> the
|
111
|
+
# concern instead of using <tt>include</tt> for it.
|
107
112
|
module Concerning
|
108
113
|
# Define a new concern and mix it in.
|
109
|
-
def concerning(topic, &block)
|
110
|
-
|
114
|
+
def concerning(topic, prepend: false, &block)
|
115
|
+
method = prepend ? :prepend : :include
|
116
|
+
__send__(method, concern(topic, &block))
|
111
117
|
end
|
112
118
|
|
113
119
|
# A low-cruft shortcut to define a concern.
|
@@ -170,7 +170,7 @@ class Module
|
|
170
170
|
# The target method must be public, otherwise it will raise +NoMethodError+.
|
171
171
|
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
|
172
172
|
unless to
|
173
|
-
raise ArgumentError, "Delegation needs a target. Supply
|
173
|
+
raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
|
174
174
|
end
|
175
175
|
|
176
176
|
if prefix == true && /^[^a-z_]/.match?(to)
|
@@ -190,7 +190,13 @@ class Module
|
|
190
190
|
to = to.to_s
|
191
191
|
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
|
192
192
|
|
193
|
-
|
193
|
+
method_def = []
|
194
|
+
method_names = []
|
195
|
+
|
196
|
+
methods.map do |method|
|
197
|
+
method_name = prefix ? "#{method_prefix}#{method}" : method
|
198
|
+
method_names << method_name.to_sym
|
199
|
+
|
194
200
|
# Attribute writer methods only accept one argument. Makes sure []=
|
195
201
|
# methods still accept two arguments.
|
196
202
|
definition = if /[^\]]=$/.match?(method)
|
@@ -209,34 +215,33 @@ class Module
|
|
209
215
|
# whereas conceptually, from the user point of view, the delegator should
|
210
216
|
# be doing one call.
|
211
217
|
if allow_nil
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
"
|
216
|
-
" _
|
217
|
-
"
|
218
|
-
|
219
|
-
|
218
|
+
method = method.to_s
|
219
|
+
|
220
|
+
method_def <<
|
221
|
+
"def #{method_name}(#{definition})" <<
|
222
|
+
" _ = #{to}" <<
|
223
|
+
" if !_.nil? || nil.respond_to?(:#{method})" <<
|
224
|
+
" _.#{method}(#{definition})" <<
|
225
|
+
" end" <<
|
226
|
+
"end"
|
220
227
|
else
|
221
|
-
|
228
|
+
method = method.to_s
|
229
|
+
method_name = method_name.to_s
|
222
230
|
|
223
|
-
method_def
|
224
|
-
"def #{
|
225
|
-
"
|
226
|
-
" _.#{method}(#{definition})"
|
227
|
-
"rescue NoMethodError => e"
|
228
|
-
" if _.nil? && e.name == :#{method}"
|
229
|
-
"
|
230
|
-
" else"
|
231
|
-
" raise"
|
232
|
-
" end"
|
231
|
+
method_def <<
|
232
|
+
"def #{method_name}(#{definition})" <<
|
233
|
+
" _ = #{to}" <<
|
234
|
+
" _.#{method}(#{definition})" <<
|
235
|
+
"rescue NoMethodError => e" <<
|
236
|
+
" if _.nil? && e.name == :#{method}" <<
|
237
|
+
%( raise DelegationError, "#{self}##{method_name} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") <<
|
238
|
+
" else" <<
|
239
|
+
" raise" <<
|
240
|
+
" end" <<
|
233
241
|
"end"
|
234
|
-
].join ";"
|
235
242
|
end
|
236
|
-
|
237
|
-
module_eval(method_def, file, line)
|
238
243
|
end
|
239
|
-
|
244
|
+
module_eval(method_def.join(";"), file, line)
|
240
245
|
private(*method_names) if private
|
241
246
|
method_names
|
242
247
|
end
|
@@ -280,13 +285,14 @@ class Module
|
|
280
285
|
# variables, methods, constants, etc.
|
281
286
|
#
|
282
287
|
# The delegated method must be public on the target, otherwise it will
|
283
|
-
# raise +
|
288
|
+
# raise +DelegationError+. If you wish to instead return +nil+,
|
289
|
+
# use the <tt>:allow_nil</tt> option.
|
284
290
|
#
|
285
291
|
# The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from
|
286
292
|
# delegation due to possible interference when calling
|
287
293
|
# <tt>Marshal.dump(object)</tt>, should the delegation target method
|
288
294
|
# of <tt>object</tt> add or remove instance variables.
|
289
|
-
def delegate_missing_to(target)
|
295
|
+
def delegate_missing_to(target, allow_nil: nil)
|
290
296
|
target = target.to_s
|
291
297
|
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
|
292
298
|
|
@@ -307,7 +313,11 @@ class Module
|
|
307
313
|
super
|
308
314
|
rescue NoMethodError
|
309
315
|
if #{target}.nil?
|
310
|
-
|
316
|
+
if #{allow_nil == true}
|
317
|
+
nil
|
318
|
+
else
|
319
|
+
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
|
320
|
+
end
|
311
321
|
else
|
312
322
|
raise
|
313
323
|
end
|
@@ -11,20 +11,12 @@ class Module
|
|
11
11
|
if defined?(@parent_name)
|
12
12
|
@parent_name
|
13
13
|
else
|
14
|
-
parent_name = name =~ /::[^:]+\
|
14
|
+
parent_name = name =~ /::[^:]+\z/ ? -$` : nil
|
15
15
|
@parent_name = parent_name unless frozen?
|
16
16
|
parent_name
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def parent_name
|
21
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
22
|
-
`Module#parent_name` has been renamed to `module_parent_name`.
|
23
|
-
`parent_name` is deprecated and will be removed in Rails 6.1.
|
24
|
-
MSG
|
25
|
-
module_parent_name
|
26
|
-
end
|
27
|
-
|
28
20
|
# Returns the module which contains this one according to its name.
|
29
21
|
#
|
30
22
|
# module M
|
@@ -44,14 +36,6 @@ class Module
|
|
44
36
|
module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
|
45
37
|
end
|
46
38
|
|
47
|
-
def parent
|
48
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
49
|
-
`Module#parent` has been renamed to `module_parent`.
|
50
|
-
`parent` is deprecated and will be removed in Rails 6.1.
|
51
|
-
MSG
|
52
|
-
module_parent
|
53
|
-
end
|
54
|
-
|
55
39
|
# Returns all the parents of this module according to its name, ordered from
|
56
40
|
# nested outwards. The receiver is not contained within the result.
|
57
41
|
#
|
@@ -76,12 +60,4 @@ class Module
|
|
76
60
|
parents << Object unless parents.include? Object
|
77
61
|
parents
|
78
62
|
end
|
79
|
-
|
80
|
-
def parents
|
81
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
82
|
-
`Module#parents` has been renamed to `module_parents`.
|
83
|
-
`parents` is deprecated and will be removed in Rails 6.1.
|
84
|
-
MSG
|
85
|
-
module_parents
|
86
|
-
end
|
87
63
|
end
|
@@ -14,9 +14,22 @@ class NameError
|
|
14
14
|
# It extends NameError#message with spell corrections which are SLOW.
|
15
15
|
# We should use original_message message instead.
|
16
16
|
message = respond_to?(:original_message) ? original_message : self.message
|
17
|
+
return unless message.start_with?("uninitialized constant ")
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
receiver = begin
|
20
|
+
self.receiver
|
21
|
+
rescue ArgumentError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
if receiver == Object
|
26
|
+
name.to_s
|
27
|
+
elsif receiver
|
28
|
+
"#{real_mod_name(receiver)}::#{self.name}"
|
29
|
+
else
|
30
|
+
if match = message.match(/((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/)
|
31
|
+
match[1]
|
32
|
+
end
|
20
33
|
end
|
21
34
|
end
|
22
35
|
|
@@ -35,4 +48,18 @@ class NameError
|
|
35
48
|
missing_name == name.to_s
|
36
49
|
end
|
37
50
|
end
|
51
|
+
|
52
|
+
private
|
53
|
+
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
54
|
+
private_constant :UNBOUND_METHOD_MODULE_NAME
|
55
|
+
|
56
|
+
if UnboundMethod.method_defined?(:bind_call)
|
57
|
+
def real_mod_name(mod)
|
58
|
+
UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
def real_mod_name(mod)
|
62
|
+
UNBOUND_METHOD_MODULE_NAME.bind(mod).call
|
63
|
+
end
|
64
|
+
end
|
38
65
|
end
|