activesupport 6.1.0 → 7.0.4.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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +263 -352
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support/actionable_error.rb +1 -1
  6. data/lib/active_support/array_inquirer.rb +0 -2
  7. data/lib/active_support/backtrace_cleaner.rb +2 -2
  8. data/lib/active_support/benchmarkable.rb +2 -2
  9. data/lib/active_support/cache/file_store.rb +16 -10
  10. data/lib/active_support/cache/mem_cache_store.rb +154 -39
  11. data/lib/active_support/cache/memory_store.rb +24 -16
  12. data/lib/active_support/cache/null_store.rb +10 -2
  13. data/lib/active_support/cache/redis_cache_store.rb +59 -78
  14. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  15. data/lib/active_support/cache.rb +306 -148
  16. data/lib/active_support/callbacks.rb +184 -85
  17. data/lib/active_support/code_generator.rb +65 -0
  18. data/lib/active_support/concern.rb +5 -5
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  20. data/lib/active_support/concurrency/share_lock.rb +2 -2
  21. data/lib/active_support/configurable.rb +8 -5
  22. data/lib/active_support/configuration_file.rb +7 -2
  23. data/lib/active_support/core_ext/array/access.rb +1 -5
  24. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  25. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  27. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  28. data/lib/active_support/core_ext/array.rb +1 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  30. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  31. data/lib/active_support/core_ext/date/blank.rb +1 -1
  32. data/lib/active_support/core_ext/date/calculations.rb +9 -9
  33. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  34. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  35. data/lib/active_support/core_ext/date.rb +1 -0
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  37. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  38. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  39. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  40. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  41. data/lib/active_support/core_ext/date_time.rb +1 -0
  42. data/lib/active_support/core_ext/digest/uuid.rb +39 -13
  43. data/lib/active_support/core_ext/enumerable.rb +101 -32
  44. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  45. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  46. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  47. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  48. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  49. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  50. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  51. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  52. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  53. data/lib/active_support/core_ext/name_error.rb +2 -8
  54. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  55. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  56. data/lib/active_support/core_ext/numeric.rb +1 -0
  57. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  58. data/lib/active_support/core_ext/object/blank.rb +2 -2
  59. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  60. data/lib/active_support/core_ext/object/duplicable.rb +11 -0
  61. data/lib/active_support/core_ext/object/json.rb +37 -25
  62. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  63. data/lib/active_support/core_ext/object/try.rb +20 -20
  64. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  65. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  66. data/lib/active_support/core_ext/pathname.rb +3 -0
  67. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  68. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  69. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  70. data/lib/active_support/core_ext/range/each.rb +1 -1
  71. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  72. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  73. data/lib/active_support/core_ext/range.rb +1 -1
  74. data/lib/active_support/core_ext/securerandom.rb +1 -1
  75. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  76. data/lib/active_support/core_ext/string/filters.rb +1 -1
  77. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  78. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  79. data/lib/active_support/core_ext/string/output_safety.rb +91 -39
  80. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  81. data/lib/active_support/core_ext/time/calculations.rb +9 -7
  82. data/lib/active_support/core_ext/time/conversions.rb +14 -12
  83. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  84. data/lib/active_support/core_ext/time/zones.rb +7 -22
  85. data/lib/active_support/core_ext/time.rb +1 -0
  86. data/lib/active_support/core_ext/uri.rb +3 -27
  87. data/lib/active_support/core_ext.rb +2 -1
  88. data/lib/active_support/current_attributes.rb +32 -14
  89. data/lib/active_support/dependencies/interlock.rb +10 -18
  90. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  91. data/lib/active_support/dependencies.rb +58 -788
  92. data/lib/active_support/deprecation/behaviors.rb +8 -5
  93. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  94. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  95. data/lib/active_support/deprecation.rb +2 -2
  96. data/lib/active_support/descendants_tracker.rb +174 -68
  97. data/lib/active_support/digest.rb +5 -3
  98. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  99. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  100. data/lib/active_support/duration.rb +81 -51
  101. data/lib/active_support/encrypted_configuration.rb +13 -2
  102. data/lib/active_support/encrypted_file.rb +13 -1
  103. data/lib/active_support/environment_inquirer.rb +1 -1
  104. data/lib/active_support/error_reporter.rb +117 -0
  105. data/lib/active_support/evented_file_update_checker.rb +3 -5
  106. data/lib/active_support/execution_context/test_helper.rb +13 -0
  107. data/lib/active_support/execution_context.rb +53 -0
  108. data/lib/active_support/execution_wrapper.rb +43 -21
  109. data/lib/active_support/executor/test_helper.rb +7 -0
  110. data/lib/active_support/fork_tracker.rb +19 -10
  111. data/lib/active_support/gem_version.rb +5 -5
  112. data/lib/active_support/hash_with_indifferent_access.rb +9 -2
  113. data/lib/active_support/html_safe_translation.rb +43 -0
  114. data/lib/active_support/i18n.rb +1 -0
  115. data/lib/active_support/i18n_railtie.rb +1 -1
  116. data/lib/active_support/inflector/inflections.rb +23 -7
  117. data/lib/active_support/inflector/methods.rb +24 -48
  118. data/lib/active_support/inflector/transliterate.rb +1 -1
  119. data/lib/active_support/isolated_execution_state.rb +72 -0
  120. data/lib/active_support/json/encoding.rb +3 -3
  121. data/lib/active_support/key_generator.rb +22 -5
  122. data/lib/active_support/lazy_load_hooks.rb +28 -4
  123. data/lib/active_support/locale/en.yml +2 -2
  124. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  125. data/lib/active_support/log_subscriber.rb +15 -5
  126. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  127. data/lib/active_support/message_encryptor.rb +12 -6
  128. data/lib/active_support/message_verifier.rb +46 -14
  129. data/lib/active_support/messages/metadata.rb +2 -2
  130. data/lib/active_support/multibyte/chars.rb +10 -11
  131. data/lib/active_support/multibyte/unicode.rb +0 -12
  132. data/lib/active_support/multibyte.rb +1 -1
  133. data/lib/active_support/notifications/fanout.rb +91 -65
  134. data/lib/active_support/notifications/instrumenter.rb +32 -15
  135. data/lib/active_support/notifications.rb +24 -24
  136. data/lib/active_support/number_helper/number_converter.rb +1 -3
  137. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  138. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  139. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  140. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  141. data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
  142. data/lib/active_support/number_helper/rounding_helper.rb +2 -6
  143. data/lib/active_support/number_helper.rb +0 -2
  144. data/lib/active_support/option_merger.rb +10 -18
  145. data/lib/active_support/ordered_hash.rb +1 -1
  146. data/lib/active_support/ordered_options.rb +1 -1
  147. data/lib/active_support/parameter_filter.rb +6 -1
  148. data/lib/active_support/per_thread_registry.rb +5 -0
  149. data/lib/active_support/railtie.rb +69 -19
  150. data/lib/active_support/reloader.rb +1 -1
  151. data/lib/active_support/rescuable.rb +16 -16
  152. data/lib/active_support/ruby_features.rb +7 -0
  153. data/lib/active_support/secure_compare_rotator.rb +2 -2
  154. data/lib/active_support/security_utils.rb +1 -1
  155. data/lib/active_support/string_inquirer.rb +0 -2
  156. data/lib/active_support/subscriber.rb +7 -18
  157. data/lib/active_support/tagged_logging.rb +2 -2
  158. data/lib/active_support/test_case.rb +13 -21
  159. data/lib/active_support/testing/assertions.rb +36 -6
  160. data/lib/active_support/testing/deprecation.rb +52 -1
  161. data/lib/active_support/testing/isolation.rb +2 -2
  162. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  163. data/lib/active_support/testing/parallelization/server.rb +4 -0
  164. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  165. data/lib/active_support/testing/parallelization.rb +4 -0
  166. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  167. data/lib/active_support/testing/stream.rb +3 -5
  168. data/lib/active_support/testing/tagged_logging.rb +1 -1
  169. data/lib/active_support/testing/time_helpers.rb +13 -2
  170. data/lib/active_support/time_with_zone.rb +60 -20
  171. data/lib/active_support/values/time_zone.rb +36 -15
  172. data/lib/active_support/version.rb +1 -1
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +5 -5
  175. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  176. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  177. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  178. data/lib/active_support/xml_mini/rexml.rb +1 -1
  179. data/lib/active_support/xml_mini.rb +5 -4
  180. data/lib/active_support.rb +17 -1
  181. metadata +29 -26
  182. data/lib/active_support/core_ext/marshal.rb +0 -26
  183. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module DeprecatedNumericWithFormat # :nodoc:
5
+ def to_s(format = nil, options = nil)
6
+ return super() if format.nil?
7
+
8
+ case format
9
+ when Integer, String
10
+ super(format)
11
+ when :phone
12
+ ActiveSupport::Deprecation.warn(
13
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
14
+ )
15
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
16
+ when :currency
17
+ ActiveSupport::Deprecation.warn(
18
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
19
+ )
20
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
21
+ when :percentage
22
+ ActiveSupport::Deprecation.warn(
23
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
24
+ )
25
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
26
+ when :delimited
27
+ ActiveSupport::Deprecation.warn(
28
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
29
+ )
30
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
31
+ when :rounded
32
+ ActiveSupport::Deprecation.warn(
33
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
34
+ )
35
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
36
+ when :human
37
+ ActiveSupport::Deprecation.warn(
38
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
39
+ )
40
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
41
+ when :human_size
42
+ ActiveSupport::Deprecation.warn(
43
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
44
+ )
45
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
46
+ when Symbol
47
+ ActiveSupport::Deprecation.warn(
48
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
49
+ )
50
+ super()
51
+ else
52
+ super(format)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ Integer.prepend ActiveSupport::DeprecatedNumericWithFormat
59
+ Float.prepend ActiveSupport::DeprecatedNumericWithFormat
60
+ BigDecimal.prepend ActiveSupport::DeprecatedNumericWithFormat
@@ -3,3 +3,4 @@
3
3
  require "active_support/core_ext/numeric/bytes"
4
4
  require "active_support/core_ext/numeric/time"
5
5
  require "active_support/core_ext/numeric/conversions"
6
+ require "active_support/core_ext/numeric/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
@@ -1,11 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Object
4
- # A duck-type assistant method. For example, Active Support extends Date
5
- # to define an <tt>acts_like_date?</tt> method, and extends Time to define
6
- # <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
7
- # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
8
- # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
4
+ # Provides a way to check whether some class acts like some other class based on the existence of
5
+ # an appropriately-named marker method.
6
+ #
7
+ # A class that provides the same interface as <tt>SomeClass</tt> may define a marker method named
8
+ # <tt>acts_like_some_class?</tt> to signal its compatibility to callers of
9
+ # <tt>acts_like?(:some_class)</tt>.
10
+ #
11
+ # For example, Active Support extends <tt>Date</tt> to define an <tt>acts_like_date?</tt> method,
12
+ # and extends <tt>Time</tt> to define <tt>acts_like_time?</tt>. As a result, developers can call
13
+ # <tt>x.acts_like?(:time)</tt> and <tt>x.acts_like?(:date)</tt> to test duck-type compatibility,
14
+ # and classes that are able to act like <tt>Time</tt> can also define an <tt>acts_like_time?</tt>
15
+ # method to interoperate.
16
+ #
17
+ # Note that the marker method is only expected to exist. It isn't called, so its body or return
18
+ # value are irrelevant.
19
+ #
20
+ # ==== Example: A class that provides the same interface as <tt>String</tt>
21
+ #
22
+ # This class may define:
23
+ #
24
+ # class Stringish
25
+ # def acts_like_string?
26
+ # end
27
+ # end
28
+ #
29
+ # Then client code can query for duck-type-safeness this way:
30
+ #
31
+ # Stringish.new.acts_like?(:string) # => true
32
+ #
9
33
  def acts_like?(duck)
10
34
  case duck
11
35
  when :time
@@ -131,7 +131,7 @@ class String
131
131
  end
132
132
  end
133
133
 
134
- class Numeric #:nodoc:
134
+ class Numeric # :nodoc:
135
135
  # No number is blank:
136
136
  #
137
137
  # 1.blank? # => false
@@ -143,7 +143,7 @@ class Numeric #:nodoc:
143
143
  end
144
144
  end
145
145
 
146
- class Time #:nodoc:
146
+ class Time # :nodoc:
147
147
  # No Time is blank:
148
148
  #
149
149
  # Time.now.blank? # => false
@@ -43,7 +43,7 @@ class Hash
43
43
  def deep_dup
44
44
  hash = dup
45
45
  each_pair do |key, value|
46
- if (::String === key && key.frozen?) || ::Symbol === key
46
+ if ::String === key || ::Symbol === key
47
47
  hash[key] = value.deep_dup
48
48
  else
49
49
  hash.delete(key)
@@ -47,3 +47,14 @@ class UnboundMethod
47
47
  false
48
48
  end
49
49
  end
50
+
51
+ require "singleton"
52
+
53
+ module Singleton
54
+ # Singleton instances are not duplicable:
55
+ #
56
+ # Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
57
+ def duplicable?
58
+ false
59
+ end
60
+ end
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Hack to load json gem first so we can overwrite its to_json.
3
+ # Hack to load json gem first so we can override its to_json.
4
4
  require "json"
5
5
  require "bigdecimal"
6
+ require "ipaddr"
6
7
  require "uri/generic"
7
8
  require "pathname"
8
9
  require "active_support/core_ext/big_decimal/conversions" # for #to_s
@@ -18,8 +19,7 @@ require "active_support/core_ext/date/conversions"
18
19
  # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
19
20
  # their default behavior. That said, we need to define the basic to_json method in all of them,
20
21
  # otherwise they will always use to_json gem implementation, which is backwards incompatible in
21
- # several cases (for instance, the JSON implementation for Hash does not work) with inheritance
22
- # and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
22
+ # several cases (for instance, the JSON implementation for Hash does not work) with inheritance.
23
23
  #
24
24
  # On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
25
25
  # JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
@@ -49,8 +49,14 @@ end
49
49
  klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
50
50
  end
51
51
 
52
+ class Module
53
+ def as_json(options = nil) # :nodoc:
54
+ name
55
+ end
56
+ end
57
+
52
58
  class Object
53
- def as_json(options = nil) #:nodoc:
59
+ def as_json(options = nil) # :nodoc:
54
60
  if respond_to?(:to_hash)
55
61
  to_hash.as_json(options)
56
62
  else
@@ -59,44 +65,44 @@ class Object
59
65
  end
60
66
  end
61
67
 
62
- class Struct #:nodoc:
68
+ class Struct # :nodoc:
63
69
  def as_json(options = nil)
64
70
  Hash[members.zip(values)].as_json(options)
65
71
  end
66
72
  end
67
73
 
68
74
  class TrueClass
69
- def as_json(options = nil) #:nodoc:
75
+ def as_json(options = nil) # :nodoc:
70
76
  self
71
77
  end
72
78
  end
73
79
 
74
80
  class FalseClass
75
- def as_json(options = nil) #:nodoc:
81
+ def as_json(options = nil) # :nodoc:
76
82
  self
77
83
  end
78
84
  end
79
85
 
80
86
  class NilClass
81
- def as_json(options = nil) #:nodoc:
87
+ def as_json(options = nil) # :nodoc:
82
88
  self
83
89
  end
84
90
  end
85
91
 
86
92
  class String
87
- def as_json(options = nil) #:nodoc:
93
+ def as_json(options = nil) # :nodoc:
88
94
  self
89
95
  end
90
96
  end
91
97
 
92
98
  class Symbol
93
- def as_json(options = nil) #:nodoc:
99
+ def as_json(options = nil) # :nodoc:
94
100
  to_s
95
101
  end
96
102
  end
97
103
 
98
104
  class Numeric
99
- def as_json(options = nil) #:nodoc:
105
+ def as_json(options = nil) # :nodoc:
100
106
  self
101
107
  end
102
108
  end
@@ -104,7 +110,7 @@ end
104
110
  class Float
105
111
  # Encoding Infinity or NaN to JSON should return "null". The default returns
106
112
  # "Infinity" or "NaN" which are not valid JSON.
107
- def as_json(options = nil) #:nodoc:
113
+ def as_json(options = nil) # :nodoc:
108
114
  finite? ? self : nil
109
115
  end
110
116
  end
@@ -119,43 +125,43 @@ class BigDecimal
119
125
  # if the other end knows by contract that the data is supposed to be a
120
126
  # BigDecimal, it still has the chance to post-process the string and get the
121
127
  # real value.
122
- def as_json(options = nil) #:nodoc:
128
+ def as_json(options = nil) # :nodoc:
123
129
  finite? ? to_s : nil
124
130
  end
125
131
  end
126
132
 
127
133
  class Regexp
128
- def as_json(options = nil) #:nodoc:
134
+ def as_json(options = nil) # :nodoc:
129
135
  to_s
130
136
  end
131
137
  end
132
138
 
133
139
  module Enumerable
134
- def as_json(options = nil) #:nodoc:
140
+ def as_json(options = nil) # :nodoc:
135
141
  to_a.as_json(options)
136
142
  end
137
143
  end
138
144
 
139
145
  class IO
140
- def as_json(options = nil) #:nodoc:
146
+ def as_json(options = nil) # :nodoc:
141
147
  to_s
142
148
  end
143
149
  end
144
150
 
145
151
  class Range
146
- def as_json(options = nil) #:nodoc:
152
+ def as_json(options = nil) # :nodoc:
147
153
  to_s
148
154
  end
149
155
  end
150
156
 
151
157
  class Array
152
- def as_json(options = nil) #:nodoc:
158
+ def as_json(options = nil) # :nodoc:
153
159
  map { |v| options ? v.as_json(options.dup) : v.as_json }
154
160
  end
155
161
  end
156
162
 
157
163
  class Hash
158
- def as_json(options = nil) #:nodoc:
164
+ def as_json(options = nil) # :nodoc:
159
165
  # create a subset of the hash by applying :only or :except
160
166
  subset = if options
161
167
  if attrs = options[:only]
@@ -178,7 +184,7 @@ class Hash
178
184
  end
179
185
 
180
186
  class Time
181
- def as_json(options = nil) #:nodoc:
187
+ def as_json(options = nil) # :nodoc:
182
188
  if ActiveSupport::JSON::Encoding.use_standard_json_time_format
183
189
  xmlschema(ActiveSupport::JSON::Encoding.time_precision)
184
190
  else
@@ -188,7 +194,7 @@ class Time
188
194
  end
189
195
 
190
196
  class Date
191
- def as_json(options = nil) #:nodoc:
197
+ def as_json(options = nil) # :nodoc:
192
198
  if ActiveSupport::JSON::Encoding.use_standard_json_time_format
193
199
  strftime("%Y-%m-%d")
194
200
  else
@@ -198,7 +204,7 @@ class Date
198
204
  end
199
205
 
200
206
  class DateTime
201
- def as_json(options = nil) #:nodoc:
207
+ def as_json(options = nil) # :nodoc:
202
208
  if ActiveSupport::JSON::Encoding.use_standard_json_time_format
203
209
  xmlschema(ActiveSupport::JSON::Encoding.time_precision)
204
210
  else
@@ -207,19 +213,25 @@ class DateTime
207
213
  end
208
214
  end
209
215
 
210
- class URI::Generic #:nodoc:
216
+ class URI::Generic # :nodoc:
217
+ def as_json(options = nil)
218
+ to_s
219
+ end
220
+ end
221
+
222
+ class Pathname # :nodoc:
211
223
  def as_json(options = nil)
212
224
  to_s
213
225
  end
214
226
  end
215
227
 
216
- class Pathname #:nodoc:
228
+ class IPAddr # :nodoc:
217
229
  def as_json(options = nil)
218
230
  to_s
219
231
  end
220
232
  end
221
233
 
222
- class Process::Status #:nodoc:
234
+ class Process::Status # :nodoc:
223
235
  def as_json(options = nil)
224
236
  { exitstatus: exitstatus, pid: pid }
225
237
  end
@@ -75,11 +75,11 @@ class Hash
75
75
  #
76
76
  # This method is also aliased as +to_param+.
77
77
  def to_query(namespace = nil)
78
- query = collect do |key, value|
78
+ query = filter_map do |key, value|
79
79
  unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
80
80
  value.to_query(namespace ? "#{namespace}[#{key}]" : key)
81
81
  end
82
- end.compact
82
+ end
83
83
 
84
84
  query.sort! unless namespace.to_s.include?("[]")
85
85
  query.join("&")
@@ -3,32 +3,32 @@
3
3
  require "delegate"
4
4
 
5
5
  module ActiveSupport
6
- module Tryable #:nodoc:
7
- def try(method_name = nil, *args, &b)
8
- if method_name.nil? && block_given?
9
- if b.arity == 0
10
- instance_eval(&b)
6
+ module Tryable # :nodoc:
7
+ def try(*args, &block)
8
+ if args.empty? && block_given?
9
+ if block.arity == 0
10
+ instance_eval(&block)
11
11
  else
12
12
  yield self
13
13
  end
14
- elsif respond_to?(method_name)
15
- public_send(method_name, *args, &b)
14
+ elsif respond_to?(args.first)
15
+ public_send(*args, &block)
16
16
  end
17
17
  end
18
- ruby2_keywords(:try) if respond_to?(:ruby2_keywords, true)
18
+ ruby2_keywords(:try)
19
19
 
20
- def try!(method_name = nil, *args, &b)
21
- if method_name.nil? && block_given?
22
- if b.arity == 0
23
- instance_eval(&b)
20
+ def try!(*args, &block)
21
+ if args.empty? && block_given?
22
+ if block.arity == 0
23
+ instance_eval(&block)
24
24
  else
25
25
  yield self
26
26
  end
27
27
  else
28
- public_send(method_name, *args, &b)
28
+ public_send(*args, &block)
29
29
  end
30
30
  end
31
- ruby2_keywords(:try!) if respond_to?(:ruby2_keywords, true)
31
+ ruby2_keywords(:try!)
32
32
  end
33
33
  end
34
34
 
@@ -39,7 +39,7 @@ class Object
39
39
  # :method: try
40
40
  #
41
41
  # :call-seq:
42
- # try(*a, &b)
42
+ # try(*args, &block)
43
43
  #
44
44
  # Invokes the public method whose name goes as first argument just like
45
45
  # +public_send+ does, except that if the receiver does not respond to it the
@@ -104,7 +104,7 @@ class Object
104
104
  # :method: try!
105
105
  #
106
106
  # :call-seq:
107
- # try!(*a, &b)
107
+ # try!(*args, &block)
108
108
  #
109
109
  # Same as #try, but raises a +NoMethodError+ exception if the receiver is
110
110
  # not +nil+ and does not implement the tried method.
@@ -121,7 +121,7 @@ class Delegator
121
121
  # :method: try
122
122
  #
123
123
  # :call-seq:
124
- # try(a*, &b)
124
+ # try(*args, &block)
125
125
  #
126
126
  # See Object#try
127
127
 
@@ -129,7 +129,7 @@ class Delegator
129
129
  # :method: try!
130
130
  #
131
131
  # :call-seq:
132
- # try!(a*, &b)
132
+ # try!(*args, &block)
133
133
  #
134
134
  # See Object#try!
135
135
  end
@@ -145,14 +145,14 @@ class NilClass
145
145
  #
146
146
  # With +try+
147
147
  # @person.try(:children).try(:first).try(:name)
148
- def try(_method_name = nil, *)
148
+ def try(*)
149
149
  nil
150
150
  end
151
151
 
152
152
  # Calling +try!+ on +nil+ always returns +nil+.
153
153
  #
154
154
  # nil.try!(:name) # => nil
155
- def try!(_method_name = nil, *)
155
+ def try!(*)
156
156
  nil
157
157
  end
158
158
  end
@@ -75,8 +75,27 @@ class Object
75
75
  # end
76
76
  # end
77
77
  #
78
+ # When the block argument is omitted, the decorated Object instance is returned:
79
+ #
80
+ # module MyStyledHelpers
81
+ # def styled
82
+ # with_options style: "color: red;"
83
+ # end
84
+ # end
85
+ #
86
+ # # styled.link_to "I'm red", "/"
87
+ # # #=> <a href="/" style="color: red;">I'm red</a>
88
+ #
89
+ # # styled.button_tag "I'm red too!"
90
+ # # #=> <button style="color: red;">I'm red too!</button>
91
+ #
78
92
  def with_options(options, &block)
79
93
  option_merger = ActiveSupport::OptionMerger.new(self, options)
80
- block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
94
+
95
+ if block
96
+ block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
97
+ else
98
+ option_merger
99
+ end
81
100
  end
82
101
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pathname
4
+ # Returns the receiver if the named file exists otherwise returns +nil+.
5
+ # <tt>pathname.existence</tt> is equivalent to
6
+ #
7
+ # pathname.exist? ? pathname : nil
8
+ #
9
+ # For example, something like
10
+ #
11
+ # content = pathname.read if pathname.exist?
12
+ #
13
+ # becomes
14
+ #
15
+ # content = pathname.existence&.read
16
+ #
17
+ # @return [Pathname]
18
+ def existence
19
+ self if exist?
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/pathname/existence"
@@ -51,31 +51,6 @@ module ActiveSupport
51
51
  super
52
52
  end
53
53
  end
54
-
55
- # Extends the default Range#cover? to support range comparisons.
56
- # (1..5).cover?(1..5) # => true
57
- # (1..5).cover?(2..3) # => true
58
- # (1..5).cover?(1...6) # => true
59
- # (1..5).cover?(2..6) # => false
60
- #
61
- # The native Range#cover? behavior is untouched.
62
- # ('a'..'f').cover?('c') # => true
63
- # (5..9).cover?(11) # => false
64
- #
65
- # The given range must be fully bounded, with both start and end.
66
- def cover?(value)
67
- if value.is_a?(::Range)
68
- is_backwards_op = value.exclude_end? ? :>= : :>
69
- return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
70
- # 1...10 covers 1..9 but it does not cover 1..10.
71
- # 1..10 covers 1...11 but it does not cover 1...12.
72
- operator = exclude_end? && !value.exclude_end? ? :< : :<=
73
- value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
74
- super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
75
- else
76
- super
77
- end
78
- end
79
54
  end
80
55
  end
81
56
 
@@ -7,34 +7,34 @@ module ActiveSupport
7
7
  case start
8
8
  when String then "BETWEEN '#{start}' AND '#{stop}'"
9
9
  else
10
- "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
10
+ "BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
11
11
  end
12
12
  end
13
13
  }
14
14
 
15
15
  # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
16
16
  #
17
+ # This method is aliased to <tt>to_formatted_s</tt>.
18
+ #
17
19
  # range = (1..100) # => 1..100
18
20
  #
19
21
  # range.to_s # => "1..100"
20
- # range.to_s(:db) # => "BETWEEN '1' AND '100'"
22
+ # range.to_fs(:db) # => "BETWEEN '1' AND '100'"
21
23
  #
22
24
  # == Adding your own range formats to to_s
23
25
  # You can add your own formats to the Range::RANGE_FORMATS hash.
24
26
  # Use the format name as the hash key and a Proc instance.
25
27
  #
26
28
  # # config/initializers/range_formats.rb
27
- # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
28
- def to_s(format = :default)
29
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
30
+ def to_fs(format = :default)
29
31
  if formatter = RANGE_FORMATS[format]
30
32
  formatter.call(first, last)
31
33
  else
32
- super()
34
+ to_s
33
35
  end
34
36
  end
35
-
36
- alias_method :to_default_s, :to_s
37
- alias_method :to_formatted_s, :to_s
37
+ alias_method :to_formatted_s, :to_fs
38
38
  end
39
39
  end
40
40
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module DeprecatedRangeWithFormat # :nodoc:
5
+ NOT_SET = Object.new # :nodoc:
6
+ def to_s(format = NOT_SET)
7
+ if formatter = RangeWithFormat::RANGE_FORMATS[format]
8
+ ActiveSupport::Deprecation.warn(
9
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
10
+ )
11
+ formatter.call(first, last)
12
+ elsif format == NOT_SET
13
+ super()
14
+ else
15
+ ActiveSupport::Deprecation.warn(
16
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
17
+ )
18
+ super()
19
+ end
20
+ end
21
+ alias_method :to_default_s, :to_s
22
+ deprecate :to_default_s
23
+ end
24
+ end
25
+
26
+ Range.prepend(ActiveSupport::DeprecatedRangeWithFormat)
@@ -3,7 +3,7 @@
3
3
  require "active_support/time_with_zone"
4
4
 
5
5
  module ActiveSupport
6
- module EachTimeWithZone #:nodoc:
6
+ module EachTimeWithZone # :nodoc:
7
7
  def each(&block)
8
8
  ensure_iteration_allowed
9
9
  super
@@ -1,28 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/time_with_zone"
4
- require "active_support/deprecation"
5
-
6
- module ActiveSupport
7
- module IncludeTimeWithZone #:nodoc:
8
- # Extends the default Range#include? to support ActiveSupport::TimeWithZone.
9
- #
10
- # (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
11
- #
12
- def include?(value)
13
- if self.begin.is_a?(TimeWithZone) || self.end.is_a?(TimeWithZone)
14
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
15
- Using `Range#include?` to check the inclusion of a value in
16
- a date time range is deprecated.
17
- It is recommended to use `Range#cover?` instead of `Range#include?` to
18
- check the inclusion of a value in a date time range.
19
- MSG
20
- cover?(value)
21
- else
22
- super
23
- end
24
- end
25
- end
26
- end
3
+ # frozen_string_literal: true
27
4
 
28
- Range.prepend(ActiveSupport::IncludeTimeWithZone)
5
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
6
+ `active_support/core_ext/range/include_time_with_zone` is deprecated and will be removed in Rails 7.1.
7
+ MSG
@@ -5,6 +5,6 @@ class Range
5
5
  # (1..5).overlaps?(4..6) # => true
6
6
  # (1..5).overlaps?(7..9) # => false
7
7
  def overlaps?(other)
8
- cover?(other.first) || other.cover?(first)
8
+ other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin)
9
9
  end
10
10
  end