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.

Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +416 -351
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -2
  5. data/lib/active_support.rb +2 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +28 -1
  8. data/lib/active_support/cache.rb +45 -23
  9. data/lib/active_support/cache/file_store.rb +22 -22
  10. data/lib/active_support/cache/mem_cache_store.rb +5 -0
  11. data/lib/active_support/cache/memory_store.rb +9 -2
  12. data/lib/active_support/cache/null_store.rb +5 -0
  13. data/lib/active_support/cache/redis_cache_store.rb +37 -10
  14. data/lib/active_support/callbacks.rb +16 -5
  15. data/lib/active_support/concern.rb +31 -4
  16. data/lib/active_support/configurable.rb +7 -11
  17. data/lib/active_support/core_ext/array.rb +1 -1
  18. data/lib/active_support/core_ext/array/access.rb +18 -6
  19. data/lib/active_support/core_ext/array/extract.rb +21 -0
  20. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  21. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  22. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  23. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  24. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  25. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  26. data/lib/active_support/core_ext/digest.rb +3 -0
  27. data/lib/active_support/core_ext/enumerable.rb +97 -73
  28. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  29. data/lib/active_support/core_ext/hash.rb +1 -2
  30. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  31. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  32. data/lib/active_support/core_ext/hash/except.rb +1 -1
  33. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  34. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  35. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  36. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  37. data/lib/active_support/core_ext/kernel.rb +0 -1
  38. data/lib/active_support/core_ext/load_error.rb +1 -1
  39. data/lib/active_support/core_ext/module.rb +0 -1
  40. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  41. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  42. data/lib/active_support/core_ext/module/delegation.rb +33 -7
  43. data/lib/active_support/core_ext/module/introspection.rb +37 -13
  44. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  45. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  46. data/lib/active_support/core_ext/numeric.rb +0 -1
  47. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  48. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  49. data/lib/active_support/core_ext/object/blank.rb +1 -2
  50. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  51. data/lib/active_support/core_ext/object/json.rb +1 -0
  52. data/lib/active_support/core_ext/object/try.rb +15 -7
  53. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  54. data/lib/active_support/core_ext/range.rb +1 -1
  55. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  56. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  57. data/lib/active_support/core_ext/range/include_range.rb +6 -22
  58. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  59. data/lib/active_support/core_ext/regexp.rb +0 -4
  60. data/lib/active_support/core_ext/securerandom.rb +23 -3
  61. data/lib/active_support/core_ext/string/access.rb +8 -0
  62. data/lib/active_support/core_ext/string/filters.rb +42 -1
  63. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  64. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  65. data/lib/active_support/core_ext/string/output_safety.rb +63 -5
  66. data/lib/active_support/core_ext/string/strip.rb +3 -1
  67. data/lib/active_support/core_ext/time/calculations.rb +31 -2
  68. data/lib/active_support/core_ext/uri.rb +2 -1
  69. data/lib/active_support/current_attributes.rb +8 -0
  70. data/lib/active_support/dependencies.rb +74 -17
  71. data/lib/active_support/dependencies/zeitwerk_integration.rb +118 -0
  72. data/lib/active_support/deprecation.rb +1 -1
  73. data/lib/active_support/deprecation/behaviors.rb +1 -1
  74. data/lib/active_support/deprecation/method_wrappers.rb +13 -12
  75. data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
  76. data/lib/active_support/descendants_tracker.rb +56 -9
  77. data/lib/active_support/duration.rb +6 -5
  78. data/lib/active_support/duration/iso8601_parser.rb +2 -3
  79. data/lib/active_support/duration/iso8601_serializer.rb +3 -4
  80. data/lib/active_support/encrypted_configuration.rb +1 -5
  81. data/lib/active_support/encrypted_file.rb +2 -1
  82. data/lib/active_support/evented_file_update_checker.rb +39 -9
  83. data/lib/active_support/execution_wrapper.rb +1 -0
  84. data/lib/active_support/gem_version.rb +3 -3
  85. data/lib/active_support/hash_with_indifferent_access.rb +36 -18
  86. data/lib/active_support/i18n.rb +1 -0
  87. data/lib/active_support/i18n_railtie.rb +14 -2
  88. data/lib/active_support/inflector/inflections.rb +1 -4
  89. data/lib/active_support/inflector/methods.rb +17 -27
  90. data/lib/active_support/inflector/transliterate.rb +47 -18
  91. data/lib/active_support/json/decoding.rb +23 -23
  92. data/lib/active_support/json/encoding.rb +6 -2
  93. data/lib/active_support/key_generator.rb +0 -32
  94. data/lib/active_support/lazy_load_hooks.rb +5 -1
  95. data/lib/active_support/locale/en.rb +31 -0
  96. data/lib/active_support/log_subscriber.rb +31 -8
  97. data/lib/active_support/logger.rb +0 -15
  98. data/lib/active_support/logger_silence.rb +28 -12
  99. data/lib/active_support/logger_thread_safe_level.rb +28 -5
  100. data/lib/active_support/message_encryptor.rb +3 -5
  101. data/lib/active_support/message_verifier.rb +3 -3
  102. data/lib/active_support/multibyte/chars.rb +29 -48
  103. data/lib/active_support/multibyte/unicode.rb +44 -281
  104. data/lib/active_support/notifications.rb +41 -4
  105. data/lib/active_support/notifications/fanout.rb +100 -15
  106. data/lib/active_support/notifications/instrumenter.rb +80 -8
  107. data/lib/active_support/number_helper.rb +7 -0
  108. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
  109. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
  110. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
  111. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
  112. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  113. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
  114. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
  115. data/lib/active_support/ordered_hash.rb +1 -1
  116. data/lib/active_support/ordered_options.rb +1 -1
  117. data/lib/active_support/parameter_filter.rb +129 -0
  118. data/lib/active_support/rails.rb +0 -6
  119. data/lib/active_support/reloader.rb +4 -5
  120. data/lib/active_support/security_utils.rb +1 -1
  121. data/lib/active_support/subscriber.rb +65 -22
  122. data/lib/active_support/tagged_logging.rb +13 -4
  123. data/lib/active_support/test_case.rb +91 -0
  124. data/lib/active_support/testing/assertions.rb +15 -1
  125. data/lib/active_support/testing/deprecation.rb +0 -1
  126. data/lib/active_support/testing/file_fixtures.rb +2 -0
  127. data/lib/active_support/testing/isolation.rb +2 -2
  128. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  129. data/lib/active_support/testing/parallelization.rb +128 -0
  130. data/lib/active_support/testing/stream.rb +1 -1
  131. data/lib/active_support/testing/time_helpers.rb +7 -7
  132. data/lib/active_support/time_with_zone.rb +15 -5
  133. data/lib/active_support/values/time_zone.rb +12 -7
  134. data/lib/active_support/xml_mini.rb +2 -9
  135. data/lib/active_support/xml_mini/jdom.rb +2 -2
  136. data/lib/active_support/xml_mini/libxml.rb +2 -2
  137. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  138. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  139. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  140. data/lib/active_support/xml_mini/rexml.rb +2 -2
  141. metadata +33 -10
  142. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  143. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -7,6 +7,6 @@ class Integer
7
7
  # 6.multiple_of?(5) # => false
8
8
  # 10.multiple_of?(2) # => true
9
9
  def multiple_of?(number)
10
- number != 0 ? self % number == 0 : zero?
10
+ number == 0 ? self == 0 : self % number == 0
11
11
  end
12
12
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/kernel/agnostics"
4
3
  require "active_support/core_ext/kernel/concern"
5
4
  require "active_support/core_ext/kernel/reporting"
6
5
  require "active_support/core_ext/kernel/singleton_class"
@@ -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.sub(/\.rb$/, "".freeze) == path.sub(/\.rb$/, "".freeze)
7
+ location.sub(/\.rb$/, "") == path.to_s.sub(/\.rb$/, "")
8
8
  end
9
9
  end
@@ -3,7 +3,6 @@
3
3
  require "active_support/core_ext/module/aliasing"
4
4
  require "active_support/core_ext/module/introspection"
5
5
  require "active_support/core_ext/module/anonymous"
6
- require "active_support/core_ext/module/reachable"
7
6
  require "active_support/core_ext/module/attribute_accessors"
8
7
  require "active_support/core_ext/module/attribute_accessors_per_thread"
9
8
  require "active_support/core_ext/module/attr_internal"
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/array/extract_options"
4
- require "active_support/core_ext/regexp"
5
-
6
3
  # Extends the module object with class/module and instance accessors for
7
4
  # class/module attributes, just like the native attr* accessors for instance
8
5
  # attributes.
@@ -27,7 +24,7 @@ class Module
27
24
  # end
28
25
  # # => NameError: invalid attribute name: 1_Badname
29
26
  #
30
- # If you want to opt out the creation on the instance reader method, pass
27
+ # To omit the instance reader method, pass
31
28
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
32
29
  #
33
30
  # module HairColors
@@ -94,7 +91,7 @@ class Module
94
91
  # Person.new.hair_colors = [:blonde, :red]
95
92
  # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
96
93
  #
97
- # If you want to opt out the instance writer method, pass
94
+ # To omit the instance writer method, pass
98
95
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
99
96
  #
100
97
  # module HairColors
@@ -163,14 +160,14 @@ class Module
163
160
  # parent class. Similarly if parent class changes the value then that would
164
161
  # change the value of subclasses too.
165
162
  #
166
- # class Male < Person
163
+ # class Citizen < Person
167
164
  # end
168
165
  #
169
- # Male.new.hair_colors << :blue
166
+ # Citizen.new.hair_colors << :blue
170
167
  # Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
171
168
  #
172
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
173
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
169
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
170
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
174
171
  #
175
172
  # module HairColors
176
173
  # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
@@ -183,7 +180,7 @@ class Module
183
180
  # Person.new.hair_colors = [:brown] # => NoMethodError
184
181
  # Person.new.hair_colors # => NoMethodError
185
182
  #
186
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
183
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
187
184
  #
188
185
  # module HairColors
189
186
  # mattr_accessor :hair_colors, instance_accessor: false
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/array/extract_options"
4
- require "active_support/core_ext/regexp"
5
-
6
3
  # Extends the module object with class/module and instance accessors for
7
4
  # class/module attributes, just like the native attr* accessors for instance
8
5
  # attributes, but does so on a per-thread basis.
@@ -28,7 +25,7 @@ class Module
28
25
  # end
29
26
  # # => NameError: invalid attribute name: 1_Badname
30
27
  #
31
- # If you want to opt out of the creation of the instance reader method, pass
28
+ # To omit the instance reader method, pass
32
29
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
33
30
  #
34
31
  # class Current
@@ -36,9 +33,7 @@ class Module
36
33
  # end
37
34
  #
38
35
  # Current.new.user # => NoMethodError
39
- def thread_mattr_reader(*syms) # :nodoc:
40
- options = syms.extract_options!
41
-
36
+ def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true) # :nodoc:
42
37
  syms.each do |sym|
43
38
  raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
44
39
 
@@ -50,7 +45,7 @@ class Module
50
45
  end
51
46
  EOS
52
47
 
53
- unless options[:instance_reader] == false || options[:instance_accessor] == false
48
+ if instance_reader && instance_accessor
54
49
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
55
50
  def #{sym}
56
51
  self.class.#{sym}
@@ -71,7 +66,7 @@ class Module
71
66
  # Current.user = "DHH"
72
67
  # Thread.current[:attr_Current_user] # => "DHH"
73
68
  #
74
- # If you want to opt out of the creation of the instance writer method, pass
69
+ # To omit the instance writer method, pass
75
70
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
76
71
  #
77
72
  # class Current
@@ -79,8 +74,7 @@ class Module
79
74
  # end
80
75
  #
81
76
  # Current.new.user = "DHH" # => NoMethodError
82
- def thread_mattr_writer(*syms) # :nodoc:
83
- options = syms.extract_options!
77
+ def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true) # :nodoc:
84
78
  syms.each do |sym|
85
79
  raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
86
80
 
@@ -92,7 +86,7 @@ class Module
92
86
  end
93
87
  EOS
94
88
 
95
- unless options[:instance_writer] == false || options[:instance_accessor] == false
89
+ if instance_writer && instance_accessor
96
90
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
97
91
  def #{sym}=(obj)
98
92
  self.class.#{sym} = obj
@@ -124,8 +118,8 @@ class Module
124
118
  # Customer.user # => "Rafael"
125
119
  # Account.user # => "DHH"
126
120
  #
127
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
128
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
121
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
122
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
129
123
  #
130
124
  # class Current
131
125
  # thread_mattr_accessor :user, instance_writer: false, instance_reader: false
@@ -134,17 +128,17 @@ class Module
134
128
  # Current.new.user = "DHH" # => NoMethodError
135
129
  # Current.new.user # => NoMethodError
136
130
  #
137
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
131
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
138
132
  #
139
133
  # class Current
140
- # mattr_accessor :user, instance_accessor: false
134
+ # thread_mattr_accessor :user, instance_accessor: false
141
135
  # end
142
136
  #
143
137
  # Current.new.user = "DHH" # => NoMethodError
144
138
  # Current.new.user # => NoMethodError
145
- def thread_mattr_accessor(*syms)
146
- thread_mattr_reader(*syms)
147
- thread_mattr_writer(*syms)
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)
141
+ thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
148
142
  end
149
143
  alias :thread_cattr_accessor :thread_mattr_accessor
150
144
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "set"
4
- require "active_support/core_ext/regexp"
5
4
 
6
5
  class Module
7
6
  # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
@@ -20,10 +19,11 @@ class Module
20
19
  # public methods as your own.
21
20
  #
22
21
  # ==== Options
23
- # * <tt>:to</tt> - Specifies the target object
22
+ # * <tt>:to</tt> - Specifies the target object name as a symbol or string
24
23
  # * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
25
- # * <tt>:allow_nil</tt> - if set to true, prevents a +Module::DelegationError+
24
+ # * <tt>:allow_nil</tt> - If set to true, prevents a +Module::DelegationError+
26
25
  # from being raised
26
+ # * <tt>:private</tt> - If set to true, changes method visibility to private
27
27
  #
28
28
  # The macro receives one or more method names (specified as symbols or
29
29
  # strings) and the name of the target object via the <tt>:to</tt> option
@@ -114,6 +114,23 @@ class Module
114
114
  # invoice.customer_name # => 'John Doe'
115
115
  # invoice.customer_address # => 'Vimmersvej 13'
116
116
  #
117
+ # The delegated methods are public by default.
118
+ # Pass <tt>private: true</tt> to change that.
119
+ #
120
+ # class User < ActiveRecord::Base
121
+ # has_one :profile
122
+ # delegate :first_name, to: :profile
123
+ # delegate :date_of_birth, to: :profile, private: true
124
+ #
125
+ # def age
126
+ # Date.today.year - date_of_birth.year
127
+ # end
128
+ # end
129
+ #
130
+ # User.new.first_name # => "Tomas"
131
+ # User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
132
+ # User.new.age # => 2
133
+ #
117
134
  # If the target is +nil+ and does not respond to the delegated method a
118
135
  # +Module::DelegationError+ is raised. If you wish to instead return +nil+,
119
136
  # use the <tt>:allow_nil</tt> option.
@@ -151,7 +168,7 @@ class Module
151
168
  # Foo.new("Bar").name # raises NoMethodError: undefined method `name'
152
169
  #
153
170
  # The target method must be public, otherwise it will raise +NoMethodError+.
154
- def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
171
+ def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
155
172
  unless to
156
173
  raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter)."
157
174
  end
@@ -173,7 +190,7 @@ class Module
173
190
  to = to.to_s
174
191
  to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
175
192
 
176
- methods.map do |method|
193
+ method_names = methods.map do |method|
177
194
  # Attribute writer methods only accept one argument. Makes sure []=
178
195
  # methods still accept two arguments.
179
196
  definition = /[^\]]=$/.match?(method) ? "arg" : "*args, &block"
@@ -213,6 +230,9 @@ class Module
213
230
 
214
231
  module_eval(method_def, file, line)
215
232
  end
233
+
234
+ private(*method_names) if private
235
+ method_names
216
236
  end
217
237
 
218
238
  # When building decorators, a common pattern may emerge:
@@ -223,7 +243,7 @@ class Module
223
243
  # end
224
244
  #
225
245
  # def person
226
- # @event.detail.person || @event.creator
246
+ # detail.person || creator
227
247
  # end
228
248
  #
229
249
  # private
@@ -246,7 +266,7 @@ class Module
246
266
  # end
247
267
  #
248
268
  # def person
249
- # @event.detail.person || @event.creator
269
+ # detail.person || creator
250
270
  # end
251
271
  # end
252
272
  #
@@ -255,6 +275,11 @@ class Module
255
275
  #
256
276
  # The delegated method must be public on the target, otherwise it will
257
277
  # raise +NoMethodError+.
278
+ #
279
+ # The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from
280
+ # delegation due to possible interference when calling
281
+ # <tt>Marshal.dump(object)</tt>, should the delegation target method
282
+ # of <tt>object</tt> add or remove instance variables.
258
283
  def delegate_missing_to(target)
259
284
  target = target.to_s
260
285
  target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
@@ -264,6 +289,7 @@ class Module
264
289
  # It may look like an oversight, but we deliberately do not pass
265
290
  # +include_private+, because they do not get delegated.
266
291
 
292
+ return false if name == :marshal_dump || name == :_dump
267
293
  #{target}.respond_to?(name) || super
268
294
  end
269
295
 
@@ -5,8 +5,8 @@ require "active_support/inflector"
5
5
  class Module
6
6
  # Returns the name of the module containing this one.
7
7
  #
8
- # M::N.parent_name # => "M"
9
- def parent_name
8
+ # M::N.module_parent_name # => "M"
9
+ def module_parent_name
10
10
  if defined?(@parent_name)
11
11
  @parent_name
12
12
  else
@@ -16,6 +16,14 @@ class Module
16
16
  end
17
17
  end
18
18
 
19
+ def parent_name
20
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
21
+ `Module#parent_name` has been renamed to `module_parent_name`.
22
+ `parent_name` is deprecated and will be removed in Rails 6.1.
23
+ MSG
24
+ module_parent_name
25
+ end
26
+
19
27
  # Returns the module which contains this one according to its name.
20
28
  #
21
29
  # module M
@@ -24,15 +32,23 @@ class Module
24
32
  # end
25
33
  # X = M::N
26
34
  #
27
- # M::N.parent # => M
28
- # X.parent # => M
35
+ # M::N.module_parent # => M
36
+ # X.module_parent # => M
29
37
  #
30
38
  # The parent of top-level and anonymous modules is Object.
31
39
  #
32
- # M.parent # => Object
33
- # Module.new.parent # => Object
40
+ # M.module_parent # => Object
41
+ # Module.new.module_parent # => Object
42
+ def module_parent
43
+ module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
44
+ end
45
+
34
46
  def parent
35
- parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
47
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
48
+ `Module#parent` has been renamed to `module_parent`.
49
+ `parent` is deprecated and will be removed in Rails 6.1.
50
+ MSG
51
+ module_parent
36
52
  end
37
53
 
38
54
  # Returns all the parents of this module according to its name, ordered from
@@ -44,13 +60,13 @@ class Module
44
60
  # end
45
61
  # X = M::N
46
62
  #
47
- # M.parents # => [Object]
48
- # M::N.parents # => [M, Object]
49
- # X.parents # => [M, Object]
50
- def parents
63
+ # M.module_parents # => [Object]
64
+ # M::N.module_parents # => [M, Object]
65
+ # X.module_parents # => [M, Object]
66
+ def module_parents
51
67
  parents = []
52
- if parent_name
53
- parts = parent_name.split("::")
68
+ if module_parent_name
69
+ parts = module_parent_name.split("::")
54
70
  until parts.empty?
55
71
  parents << ActiveSupport::Inflector.constantize(parts * "::")
56
72
  parts.pop
@@ -59,4 +75,12 @@ class Module
59
75
  parents << Object unless parents.include? Object
60
76
  parents
61
77
  end
78
+
79
+ def parents
80
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
81
+ `Module#parents` has been renamed to `module_parents`.
82
+ `parents` is deprecated and will be removed in Rails 6.1.
83
+ MSG
84
+ module_parents
85
+ end
62
86
  end
@@ -3,9 +3,4 @@
3
3
  require "active_support/core_ext/module/anonymous"
4
4
  require "active_support/core_ext/string/inflections"
5
5
 
6
- class Module
7
- def reachable? #:nodoc:
8
- !anonymous? && name.safe_constantize.equal?(self)
9
- end
10
- deprecate :reachable?
11
- end
6
+ ActiveSupport::Deprecation.warn("reachable is deprecated and will be removed from the framework.")
@@ -1,23 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Module
4
- if RUBY_VERSION >= "2.3"
5
- # Marks the named method as intended to be redefined, if it exists.
6
- # Suppresses the Ruby method redefinition warning. Prefer
7
- # #redefine_method where possible.
8
- def silence_redefinition_of_method(method)
9
- if method_defined?(method) || private_method_defined?(method)
10
- # This suppresses the "method redefined" warning; the self-alias
11
- # looks odd, but means we don't need to generate a unique name
12
- alias_method method, method
13
- end
14
- end
15
- else
16
- def silence_redefinition_of_method(method)
17
- if method_defined?(method) || private_method_defined?(method)
18
- alias_method :__rails_redefine, method
19
- remove_method :__rails_redefine
20
- end
4
+ # Marks the named method as intended to be redefined, if it exists.
5
+ # Suppresses the Ruby method redefinition warning. Prefer
6
+ # #redefine_method where possible.
7
+ def silence_redefinition_of_method(method)
8
+ if method_defined?(method) || private_method_defined?(method)
9
+ # This suppresses the "method redefined" warning; the self-alias
10
+ # looks odd, but means we don't need to generate a unique name
11
+ alias_method method, method
21
12
  end
22
13
  end
23
14
 
@@ -2,5 +2,4 @@
2
2
 
3
3
  require "active_support/core_ext/numeric/bytes"
4
4
  require "active_support/core_ext/numeric/time"
5
- require "active_support/core_ext/numeric/inquiry"
6
5
  require "active_support/core_ext/numeric/conversions"
@@ -4,137 +4,133 @@ require "active_support/core_ext/big_decimal/conversions"
4
4
  require "active_support/number_helper"
5
5
  require "active_support/core_ext/module/deprecation"
6
6
 
7
- module ActiveSupport::NumericWithFormat
8
- # Provides options for converting numbers into formatted strings.
9
- # Options are provided for phone numbers, currency, percentage,
10
- # precision, positional notation, file size and pretty printing.
11
- #
12
- # ==== Options
13
- #
14
- # For details on which formats use which options, see ActiveSupport::NumberHelper
15
- #
16
- # ==== Examples
17
- #
18
- # Phone Numbers:
19
- # 5551234.to_s(:phone) # => "555-1234"
20
- # 1235551234.to_s(:phone) # => "123-555-1234"
21
- # 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
22
- # 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
23
- # 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
24
- # 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
25
- # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
26
- # # => "+1.123.555.1234 x 1343"
27
- #
28
- # Currency:
29
- # 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
30
- # 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
31
- # 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
32
- # 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
33
- # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
34
- # # => "($1,234,567,890.50)"
35
- # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
36
- # # => "&pound;1234567890,50"
37
- # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
38
- # # => "1234567890,50 &pound;"
39
- #
40
- # Percentage:
41
- # 100.to_s(:percentage) # => "100.000%"
42
- # 100.to_s(:percentage, precision: 0) # => "100%"
43
- # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
44
- # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
45
- # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
46
- # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
47
- #
48
- # Delimited:
49
- # 12345678.to_s(:delimited) # => "12,345,678"
50
- # 12345678.05.to_s(:delimited) # => "12,345,678.05"
51
- # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
52
- # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
53
- # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
54
- # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
55
- # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
56
- # # => "98 765 432,98"
57
- #
58
- # Rounded:
59
- # 111.2345.to_s(:rounded) # => "111.235"
60
- # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
61
- # 13.to_s(:rounded, precision: 5) # => "13.00000"
62
- # 389.32314.to_s(:rounded, precision: 0) # => "389"
63
- # 111.2345.to_s(:rounded, significant: true) # => "111"
64
- # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
65
- # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
66
- # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
67
- # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
68
- # # => "13"
69
- # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
70
- # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
71
- # # => "1.111,23"
72
- #
73
- # Human-friendly size in Bytes:
74
- # 123.to_s(:human_size) # => "123 Bytes"
75
- # 1234.to_s(:human_size) # => "1.21 KB"
76
- # 12345.to_s(:human_size) # => "12.1 KB"
77
- # 1234567.to_s(:human_size) # => "1.18 MB"
78
- # 1234567890.to_s(:human_size) # => "1.15 GB"
79
- # 1234567890123.to_s(:human_size) # => "1.12 TB"
80
- # 1234567890123456.to_s(:human_size) # => "1.1 PB"
81
- # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
82
- # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
83
- # 483989.to_s(:human_size, precision: 2) # => "470 KB"
84
- # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
85
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
86
- # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
87
- #
88
- # Human-friendly format:
89
- # 123.to_s(:human) # => "123"
90
- # 1234.to_s(:human) # => "1.23 Thousand"
91
- # 12345.to_s(:human) # => "12.3 Thousand"
92
- # 1234567.to_s(:human) # => "1.23 Million"
93
- # 1234567890.to_s(:human) # => "1.23 Billion"
94
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
95
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
96
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
97
- # 489939.to_s(:human, precision: 2) # => "490 Thousand"
98
- # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
99
- # 1234567.to_s(:human, precision: 4,
100
- # significant: false) # => "1.2346 Million"
101
- # 1234567.to_s(:human, precision: 1,
102
- # separator: ',',
103
- # significant: false) # => "1,2 Million"
104
- def to_s(format = nil, options = nil)
105
- case format
106
- when nil
107
- super()
108
- when Integer, String
109
- super(format)
110
- when :phone
111
- ActiveSupport::NumberHelper.number_to_phone(self, options || {})
112
- when :currency
113
- ActiveSupport::NumberHelper.number_to_currency(self, options || {})
114
- when :percentage
115
- ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
116
- when :delimited
117
- ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
118
- when :rounded
119
- ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
120
- when :human
121
- ActiveSupport::NumberHelper.number_to_human(self, options || {})
122
- when :human_size
123
- ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
124
- when Symbol
125
- super()
126
- else
127
- super(format)
7
+ module ActiveSupport
8
+ module NumericWithFormat
9
+ # Provides options for converting numbers into formatted strings.
10
+ # Options are provided for phone numbers, currency, percentage,
11
+ # precision, positional notation, file size and pretty printing.
12
+ #
13
+ # ==== Options
14
+ #
15
+ # For details on which formats use which options, see ActiveSupport::NumberHelper
16
+ #
17
+ # ==== Examples
18
+ #
19
+ # Phone Numbers:
20
+ # 5551234.to_s(:phone) # => "555-1234"
21
+ # 1235551234.to_s(:phone) # => "123-555-1234"
22
+ # 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
23
+ # 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
24
+ # 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
25
+ # 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
26
+ # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
27
+ # # => "+1.123.555.1234 x 1343"
28
+ #
29
+ # Currency:
30
+ # 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
31
+ # 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
32
+ # 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
33
+ # 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
34
+ # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
35
+ # # => "($1,234,567,890.50)"
36
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
37
+ # # => "&pound;1234567890,50"
38
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
39
+ # # => "1234567890,50 &pound;"
40
+ #
41
+ # Percentage:
42
+ # 100.to_s(:percentage) # => "100.000%"
43
+ # 100.to_s(:percentage, precision: 0) # => "100%"
44
+ # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
45
+ # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
46
+ # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
47
+ # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
48
+ #
49
+ # Delimited:
50
+ # 12345678.to_s(:delimited) # => "12,345,678"
51
+ # 12345678.05.to_s(:delimited) # => "12,345,678.05"
52
+ # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
53
+ # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
54
+ # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
55
+ # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
56
+ # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
57
+ # # => "98 765 432,98"
58
+ #
59
+ # Rounded:
60
+ # 111.2345.to_s(:rounded) # => "111.235"
61
+ # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
62
+ # 13.to_s(:rounded, precision: 5) # => "13.00000"
63
+ # 389.32314.to_s(:rounded, precision: 0) # => "389"
64
+ # 111.2345.to_s(:rounded, significant: true) # => "111"
65
+ # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
66
+ # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
67
+ # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
68
+ # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
69
+ # # => "13"
70
+ # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
71
+ # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
72
+ # # => "1.111,23"
73
+ #
74
+ # Human-friendly size in Bytes:
75
+ # 123.to_s(:human_size) # => "123 Bytes"
76
+ # 1234.to_s(:human_size) # => "1.21 KB"
77
+ # 12345.to_s(:human_size) # => "12.1 KB"
78
+ # 1234567.to_s(:human_size) # => "1.18 MB"
79
+ # 1234567890.to_s(:human_size) # => "1.15 GB"
80
+ # 1234567890123.to_s(:human_size) # => "1.12 TB"
81
+ # 1234567890123456.to_s(:human_size) # => "1.1 PB"
82
+ # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
83
+ # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
84
+ # 483989.to_s(:human_size, precision: 2) # => "470 KB"
85
+ # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
86
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
87
+ # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
88
+ #
89
+ # Human-friendly format:
90
+ # 123.to_s(:human) # => "123"
91
+ # 1234.to_s(:human) # => "1.23 Thousand"
92
+ # 12345.to_s(:human) # => "12.3 Thousand"
93
+ # 1234567.to_s(:human) # => "1.23 Million"
94
+ # 1234567890.to_s(:human) # => "1.23 Billion"
95
+ # 1234567890123.to_s(:human) # => "1.23 Trillion"
96
+ # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
97
+ # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
98
+ # 489939.to_s(:human, precision: 2) # => "490 Thousand"
99
+ # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
100
+ # 1234567.to_s(:human, precision: 4,
101
+ # significant: false) # => "1.2346 Million"
102
+ # 1234567.to_s(:human, precision: 1,
103
+ # separator: ',',
104
+ # significant: false) # => "1,2 Million"
105
+ def to_s(format = nil, options = nil)
106
+ case format
107
+ when nil
108
+ super()
109
+ when Integer, String
110
+ super(format)
111
+ when :phone
112
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
113
+ when :currency
114
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
115
+ when :percentage
116
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
117
+ when :delimited
118
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
119
+ when :rounded
120
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
121
+ when :human
122
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
123
+ when :human_size
124
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
125
+ when Symbol
126
+ super()
127
+ else
128
+ super(format)
129
+ end
128
130
  end
129
131
  end
130
132
  end
131
133
 
132
- # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
133
- if 0.class == Integer
134
- Integer.prepend ActiveSupport::NumericWithFormat
135
- else
136
- Fixnum.prepend ActiveSupport::NumericWithFormat
137
- Bignum.prepend ActiveSupport::NumericWithFormat
138
- end
134
+ Integer.prepend ActiveSupport::NumericWithFormat
139
135
  Float.prepend ActiveSupport::NumericWithFormat
140
136
  BigDecimal.prepend ActiveSupport::NumericWithFormat