activesupport 6.1.4.6 → 7.0.0.alpha1
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 +151 -551
- data/MIT-LICENSE +1 -1
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +119 -28
- data/lib/active_support/cache/memory_store.rb +21 -13
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +39 -59
- data/lib/active_support/cache/strategy/local_cache.rb +29 -49
- data/lib/active_support/cache.rb +189 -45
- data/lib/active_support/callbacks.rb +35 -31
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +6 -3
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +6 -6
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +2 -2
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/digest/uuid.rb +13 -12
- data/lib/active_support/core_ext/enumerable.rb +64 -12
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +2 -2
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +11 -0
- data/lib/active_support/core_ext/object/json.rb +29 -24
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +60 -36
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +6 -5
- data/lib/active_support/core_ext/time/zones.rb +2 -17
- data/lib/active_support/core_ext/uri.rb +1 -15
- data/lib/active_support/current_attributes.rb +17 -1
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +4 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/descendants_tracker.rb +12 -9
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +77 -48
- data/lib/active_support/encrypted_configuration.rb +11 -1
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/evented_file_update_checker.rb +1 -1
- data/lib/active_support/execution_wrapper.rb +13 -16
- data/lib/active_support/fork_tracker.rb +2 -4
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/inflector/inflections.rb +11 -4
- data/lib/active_support/inflector/methods.rb +23 -47
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +18 -1
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber.rb +13 -3
- data/lib/active_support/logger_thread_safe_level.rb +5 -13
- data/lib/active_support/message_encryptor.rb +3 -3
- data/lib/active_support/message_verifier.rb +4 -4
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +2 -2
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +31 -11
- data/lib/active_support/notifications/instrumenter.rb +17 -0
- data/lib/active_support/notifications.rb +10 -0
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_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_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +0 -2
- data/lib/active_support/option_merger.rb +4 -16
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/parameter_filter.rb +5 -0
- data/lib/active_support/per_thread_registry.rb +1 -0
- data/lib/active_support/railtie.rb +34 -11
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +2 -2
- data/lib/active_support/secure_compare_rotator.rb +1 -1
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +5 -0
- data/lib/active_support/tagged_logging.rb +1 -1
- data/lib/active_support/test_case.rb +9 -21
- data/lib/active_support/testing/assertions.rb +35 -5
- data/lib/active_support/testing/deprecation.rb +1 -1
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +19 -6
- data/lib/active_support/values/time_zone.rb +25 -9
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +2 -1
- data/lib/active_support.rb +14 -1
- metadata +14 -28
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -19,8 +19,7 @@ require "active_support/core_ext/date/conversions"
|
|
19
19
|
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
20
20
|
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
21
21
|
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
22
|
-
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
|
23
|
-
# 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.
|
24
23
|
#
|
25
24
|
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
26
25
|
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
@@ -50,8 +49,14 @@ end
|
|
50
49
|
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
51
50
|
end
|
52
51
|
|
52
|
+
class Module
|
53
|
+
def as_json(options = nil) # :nodoc:
|
54
|
+
name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
53
58
|
class Object
|
54
|
-
def as_json(options = nil)
|
59
|
+
def as_json(options = nil) # :nodoc:
|
55
60
|
if respond_to?(:to_hash)
|
56
61
|
to_hash.as_json(options)
|
57
62
|
else
|
@@ -60,44 +65,44 @@ class Object
|
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
63
|
-
class Struct
|
68
|
+
class Struct # :nodoc:
|
64
69
|
def as_json(options = nil)
|
65
70
|
Hash[members.zip(values)].as_json(options)
|
66
71
|
end
|
67
72
|
end
|
68
73
|
|
69
74
|
class TrueClass
|
70
|
-
def as_json(options = nil)
|
75
|
+
def as_json(options = nil) # :nodoc:
|
71
76
|
self
|
72
77
|
end
|
73
78
|
end
|
74
79
|
|
75
80
|
class FalseClass
|
76
|
-
def as_json(options = nil)
|
81
|
+
def as_json(options = nil) # :nodoc:
|
77
82
|
self
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
81
86
|
class NilClass
|
82
|
-
def as_json(options = nil)
|
87
|
+
def as_json(options = nil) # :nodoc:
|
83
88
|
self
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
87
92
|
class String
|
88
|
-
def as_json(options = nil)
|
93
|
+
def as_json(options = nil) # :nodoc:
|
89
94
|
self
|
90
95
|
end
|
91
96
|
end
|
92
97
|
|
93
98
|
class Symbol
|
94
|
-
def as_json(options = nil)
|
99
|
+
def as_json(options = nil) # :nodoc:
|
95
100
|
to_s
|
96
101
|
end
|
97
102
|
end
|
98
103
|
|
99
104
|
class Numeric
|
100
|
-
def as_json(options = nil)
|
105
|
+
def as_json(options = nil) # :nodoc:
|
101
106
|
self
|
102
107
|
end
|
103
108
|
end
|
@@ -105,7 +110,7 @@ end
|
|
105
110
|
class Float
|
106
111
|
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
107
112
|
# "Infinity" or "NaN" which are not valid JSON.
|
108
|
-
def as_json(options = nil)
|
113
|
+
def as_json(options = nil) # :nodoc:
|
109
114
|
finite? ? self : nil
|
110
115
|
end
|
111
116
|
end
|
@@ -120,43 +125,43 @@ class BigDecimal
|
|
120
125
|
# if the other end knows by contract that the data is supposed to be a
|
121
126
|
# BigDecimal, it still has the chance to post-process the string and get the
|
122
127
|
# real value.
|
123
|
-
def as_json(options = nil)
|
128
|
+
def as_json(options = nil) # :nodoc:
|
124
129
|
finite? ? to_s : nil
|
125
130
|
end
|
126
131
|
end
|
127
132
|
|
128
133
|
class Regexp
|
129
|
-
def as_json(options = nil)
|
134
|
+
def as_json(options = nil) # :nodoc:
|
130
135
|
to_s
|
131
136
|
end
|
132
137
|
end
|
133
138
|
|
134
139
|
module Enumerable
|
135
|
-
def as_json(options = nil)
|
140
|
+
def as_json(options = nil) # :nodoc:
|
136
141
|
to_a.as_json(options)
|
137
142
|
end
|
138
143
|
end
|
139
144
|
|
140
145
|
class IO
|
141
|
-
def as_json(options = nil)
|
146
|
+
def as_json(options = nil) # :nodoc:
|
142
147
|
to_s
|
143
148
|
end
|
144
149
|
end
|
145
150
|
|
146
151
|
class Range
|
147
|
-
def as_json(options = nil)
|
152
|
+
def as_json(options = nil) # :nodoc:
|
148
153
|
to_s
|
149
154
|
end
|
150
155
|
end
|
151
156
|
|
152
157
|
class Array
|
153
|
-
def as_json(options = nil)
|
158
|
+
def as_json(options = nil) # :nodoc:
|
154
159
|
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
155
160
|
end
|
156
161
|
end
|
157
162
|
|
158
163
|
class Hash
|
159
|
-
def as_json(options = nil)
|
164
|
+
def as_json(options = nil) # :nodoc:
|
160
165
|
# create a subset of the hash by applying :only or :except
|
161
166
|
subset = if options
|
162
167
|
if attrs = options[:only]
|
@@ -179,7 +184,7 @@ class Hash
|
|
179
184
|
end
|
180
185
|
|
181
186
|
class Time
|
182
|
-
def as_json(options = nil)
|
187
|
+
def as_json(options = nil) # :nodoc:
|
183
188
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
184
189
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
185
190
|
else
|
@@ -189,7 +194,7 @@ class Time
|
|
189
194
|
end
|
190
195
|
|
191
196
|
class Date
|
192
|
-
def as_json(options = nil)
|
197
|
+
def as_json(options = nil) # :nodoc:
|
193
198
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
194
199
|
strftime("%Y-%m-%d")
|
195
200
|
else
|
@@ -199,7 +204,7 @@ class Date
|
|
199
204
|
end
|
200
205
|
|
201
206
|
class DateTime
|
202
|
-
def as_json(options = nil)
|
207
|
+
def as_json(options = nil) # :nodoc:
|
203
208
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
204
209
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
205
210
|
else
|
@@ -208,13 +213,13 @@ class DateTime
|
|
208
213
|
end
|
209
214
|
end
|
210
215
|
|
211
|
-
class URI::Generic
|
216
|
+
class URI::Generic # :nodoc:
|
212
217
|
def as_json(options = nil)
|
213
218
|
to_s
|
214
219
|
end
|
215
220
|
end
|
216
221
|
|
217
|
-
class Pathname
|
222
|
+
class Pathname # :nodoc:
|
218
223
|
def as_json(options = nil)
|
219
224
|
to_s
|
220
225
|
end
|
@@ -226,7 +231,7 @@ class IPAddr # :nodoc:
|
|
226
231
|
end
|
227
232
|
end
|
228
233
|
|
229
|
-
class Process::Status
|
234
|
+
class Process::Status # :nodoc:
|
230
235
|
def as_json(options = nil)
|
231
236
|
{ exitstatus: exitstatus, pid: pid }
|
232
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 =
|
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
|
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
|
7
|
-
def try(
|
8
|
-
if
|
9
|
-
if
|
10
|
-
instance_eval(&
|
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?(
|
15
|
-
public_send(
|
14
|
+
elsif respond_to?(args.first)
|
15
|
+
public_send(*args, &block)
|
16
16
|
end
|
17
17
|
end
|
18
|
-
ruby2_keywords(:try)
|
18
|
+
ruby2_keywords(:try)
|
19
19
|
|
20
|
-
def try!(
|
21
|
-
if
|
22
|
-
if
|
23
|
-
instance_eval(&
|
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(
|
28
|
+
public_send(*args, &block)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
ruby2_keywords(:try!)
|
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(*
|
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!(*
|
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(
|
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!(
|
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(
|
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!(
|
155
|
+
def try!(*)
|
156
156
|
nil
|
157
157
|
end
|
158
158
|
end
|
@@ -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
|
|
@@ -4,7 +4,7 @@ require "active_support/time_with_zone"
|
|
4
4
|
require "active_support/deprecation"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
-
module IncludeTimeWithZone
|
7
|
+
module IncludeTimeWithZone # :nodoc:
|
8
8
|
# Extends the default Range#include? to support ActiveSupport::TimeWithZone.
|
9
9
|
#
|
10
10
|
# (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
|
@@ -260,7 +260,7 @@ class String
|
|
260
260
|
# 'author_id'.humanize # => "Author"
|
261
261
|
# 'author_id'.humanize(capitalize: false) # => "author"
|
262
262
|
# '_id'.humanize # => "Id"
|
263
|
-
# 'author_id'.humanize(keep_id_suffix: true) # => "Author
|
263
|
+
# 'author_id'.humanize(keep_id_suffix: true) # => "Author id"
|
264
264
|
#
|
265
265
|
# See ActiveSupport::Inflector.humanize.
|
266
266
|
def humanize(capitalize: true, keep_id_suffix: false)
|
@@ -130,7 +130,7 @@ class Numeric
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
module ActiveSupport
|
133
|
+
module ActiveSupport # :nodoc:
|
134
134
|
class SafeBuffer < String
|
135
135
|
UNSAFE_STRING_METHODS = %w(
|
136
136
|
capitalize chomp chop delete delete_prefix delete_suffix
|
@@ -184,27 +184,30 @@ module ActiveSupport #:nodoc:
|
|
184
184
|
end
|
185
185
|
|
186
186
|
def concat(value)
|
187
|
-
|
187
|
+
unless value.nil?
|
188
|
+
super(implicit_html_escape_interpolated_argument(value))
|
189
|
+
end
|
190
|
+
self
|
188
191
|
end
|
189
192
|
alias << concat
|
190
193
|
|
191
194
|
def insert(index, value)
|
192
|
-
super(index,
|
195
|
+
super(index, implicit_html_escape_interpolated_argument(value))
|
193
196
|
end
|
194
197
|
|
195
198
|
def prepend(value)
|
196
|
-
super(
|
199
|
+
super(implicit_html_escape_interpolated_argument(value))
|
197
200
|
end
|
198
201
|
|
199
202
|
def replace(value)
|
200
|
-
super(
|
203
|
+
super(implicit_html_escape_interpolated_argument(value))
|
201
204
|
end
|
202
205
|
|
203
206
|
def []=(*args)
|
204
207
|
if args.length == 3
|
205
|
-
super(args[0], args[1],
|
208
|
+
super(args[0], args[1], implicit_html_escape_interpolated_argument(args[2]))
|
206
209
|
else
|
207
|
-
super(args[0],
|
210
|
+
super(args[0], implicit_html_escape_interpolated_argument(args[1]))
|
208
211
|
end
|
209
212
|
end
|
210
213
|
|
@@ -222,9 +225,9 @@ module ActiveSupport #:nodoc:
|
|
222
225
|
def %(args)
|
223
226
|
case args
|
224
227
|
when Hash
|
225
|
-
escaped_args = args.transform_values { |arg|
|
228
|
+
escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
|
226
229
|
else
|
227
|
-
escaped_args = Array(args).map { |arg|
|
230
|
+
escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
|
228
231
|
end
|
229
232
|
|
230
233
|
self.class.new(super(escaped_args))
|
@@ -262,39 +265,60 @@ module ActiveSupport #:nodoc:
|
|
262
265
|
end
|
263
266
|
|
264
267
|
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
EOT
|
290
|
-
end
|
268
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
269
|
+
def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
|
270
|
+
if block # if block
|
271
|
+
to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
|
272
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
273
|
+
block.call(*params) # block.call(*params)
|
274
|
+
} # }
|
275
|
+
else # else
|
276
|
+
to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
|
277
|
+
end # end
|
278
|
+
end # end
|
279
|
+
|
280
|
+
def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
|
281
|
+
@html_safe = false # @html_safe = false
|
282
|
+
if block # if block
|
283
|
+
super(*args) { |*params| # super(*args) { |*params|
|
284
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
285
|
+
block.call(*params) # block.call(*params)
|
286
|
+
} # }
|
287
|
+
else # else
|
288
|
+
super # super
|
289
|
+
end # end
|
290
|
+
end # end
|
291
|
+
EOT
|
291
292
|
end
|
292
293
|
|
293
294
|
private
|
294
|
-
def
|
295
|
+
def explicit_html_escape_interpolated_argument(arg)
|
295
296
|
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
296
297
|
end
|
297
298
|
|
299
|
+
def implicit_html_escape_interpolated_argument(arg)
|
300
|
+
if !html_safe? || arg.html_safe?
|
301
|
+
arg
|
302
|
+
else
|
303
|
+
arg_string = begin
|
304
|
+
arg.to_str
|
305
|
+
rescue NoMethodError => error
|
306
|
+
if error.name == :to_str
|
307
|
+
str = arg.to_s
|
308
|
+
ActiveSupport::Deprecation.warn <<~MSG.squish
|
309
|
+
Implicit conversion of #{arg.class} into String by ActiveSupport::SafeBuffer
|
310
|
+
is deprecated and will be removed in Rails 7.1.
|
311
|
+
You must explicitly cast it to a String.
|
312
|
+
MSG
|
313
|
+
str
|
314
|
+
else
|
315
|
+
raise
|
316
|
+
end
|
317
|
+
end
|
318
|
+
CGI.escapeHTML(arg_string)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
298
322
|
def set_block_back_references(block, match_data)
|
299
323
|
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
300
324
|
rescue ArgumentError
|
@@ -1,14 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Symbol
|
4
|
-
def start_with?(*prefixes)
|
5
|
-
to_s.start_with?(*prefixes)
|
6
|
-
end unless method_defined?(:start_with?)
|
7
|
-
|
8
|
-
def end_with?(*suffixes)
|
9
|
-
to_s.end_with?(*suffixes)
|
10
|
-
end unless method_defined?(:end_with?)
|
11
|
-
|
12
4
|
alias :starts_with? :start_with?
|
13
5
|
alias :ends_with? :end_with?
|
14
6
|
end
|
@@ -42,8 +42,8 @@ class Time
|
|
42
42
|
|
43
43
|
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
|
44
44
|
# instances can be used when called with a single argument
|
45
|
-
def at_with_coercion(*args)
|
46
|
-
return at_without_coercion(*args) if args.size != 1
|
45
|
+
def at_with_coercion(*args, **kwargs)
|
46
|
+
return at_without_coercion(*args, **kwargs) if args.size != 1 || !kwargs.empty?
|
47
47
|
|
48
48
|
# Time.at can be called with a time or numerical value
|
49
49
|
time_or_number = args.first
|
@@ -56,7 +56,6 @@ class Time
|
|
56
56
|
at_without_coercion(time_or_number)
|
57
57
|
end
|
58
58
|
end
|
59
|
-
ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
|
60
59
|
alias_method :at_without_coercion, :at
|
61
60
|
alias_method :at, :at_with_coercion
|
62
61
|
|
@@ -160,6 +159,8 @@ class Time
|
|
160
159
|
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
161
160
|
elsif utc?
|
162
161
|
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
162
|
+
elsif zone&.respond_to?(:utc_to_local)
|
163
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
|
163
164
|
elsif zone
|
164
165
|
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
165
166
|
else
|
@@ -276,7 +277,7 @@ class Time
|
|
276
277
|
end
|
277
278
|
alias :at_end_of_minute :end_of_minute
|
278
279
|
|
279
|
-
def plus_with_duration(other)
|
280
|
+
def plus_with_duration(other) # :nodoc:
|
280
281
|
if ActiveSupport::Duration === other
|
281
282
|
other.since(self)
|
282
283
|
else
|
@@ -286,7 +287,7 @@ class Time
|
|
286
287
|
alias_method :plus_without_duration, :+
|
287
288
|
alias_method :+, :plus_with_duration
|
288
289
|
|
289
|
-
def minus_with_duration(other)
|
290
|
+
def minus_with_duration(other) # :nodoc:
|
290
291
|
if ActiveSupport::Duration === other
|
291
292
|
other.until(self)
|
292
293
|
else
|
@@ -80,24 +80,9 @@ class Time
|
|
80
80
|
# Time.find_zone! false # => false
|
81
81
|
# Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
|
82
82
|
def find_zone!(time_zone)
|
83
|
-
|
84
|
-
time_zone
|
85
|
-
else
|
86
|
-
# Look up the timezone based on the identifier (unless we've been
|
87
|
-
# passed a TZInfo::Timezone)
|
88
|
-
unless time_zone.respond_to?(:period_for_local)
|
89
|
-
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
90
|
-
end
|
83
|
+
return time_zone unless time_zone
|
91
84
|
|
92
|
-
|
93
|
-
if time_zone.is_a?(ActiveSupport::TimeZone)
|
94
|
-
time_zone
|
95
|
-
else
|
96
|
-
ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
rescue TZInfo::InvalidTimezoneIdentifier
|
100
|
-
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
85
|
+
ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}")
|
101
86
|
end
|
102
87
|
|
103
88
|
# Returns a TimeZone instance matching the time zone provided.
|
@@ -2,25 +2,11 @@
|
|
2
2
|
|
3
3
|
require "uri"
|
4
4
|
|
5
|
-
if RUBY_VERSION < "2.6.0"
|
6
|
-
require "active_support/core_ext/module/redefine_method"
|
7
|
-
URI::Parser.class_eval do
|
8
|
-
silence_redefinition_of_method :unescape
|
9
|
-
def unescape(str, escaped = /%[a-fA-F\d]{2}/)
|
10
|
-
# TODO: Are we actually sure that ASCII == UTF-8?
|
11
|
-
# YK: My initial experiments say yes, but let's be sure please
|
12
|
-
enc = str.encoding
|
13
|
-
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
14
|
-
str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
5
|
module URI
|
20
6
|
class << self
|
21
7
|
def parser
|
22
8
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
23
|
-
URI.parser is deprecated and will be removed in Rails
|
9
|
+
URI.parser is deprecated and will be removed in Rails 7.0.
|
24
10
|
Use `URI::DEFAULT_PARSER` instead.
|
25
11
|
MSG
|
26
12
|
URI::DEFAULT_PARSER
|
@@ -143,13 +143,24 @@ module ActiveSupport
|
|
143
143
|
current_instances.clear
|
144
144
|
end
|
145
145
|
|
146
|
+
def _use_thread_variables=(value) # :nodoc:
|
147
|
+
clear_all
|
148
|
+
@@use_thread_variables = value
|
149
|
+
end
|
150
|
+
@@use_thread_variables = false
|
151
|
+
|
146
152
|
private
|
147
153
|
def generated_attribute_methods
|
148
154
|
@generated_attribute_methods ||= Module.new.tap { |mod| include mod }
|
149
155
|
end
|
150
156
|
|
151
157
|
def current_instances
|
152
|
-
|
158
|
+
if @@use_thread_variables
|
159
|
+
Thread.current.thread_variable_get(:current_attributes_instances) ||
|
160
|
+
Thread.current.thread_variable_set(:current_attributes_instances, {})
|
161
|
+
else
|
162
|
+
Thread.current[:current_attributes_instances] ||= {}
|
163
|
+
end
|
153
164
|
end
|
154
165
|
|
155
166
|
def current_instances_key
|
@@ -164,6 +175,11 @@ module ActiveSupport
|
|
164
175
|
|
165
176
|
send(name, *args, &block)
|
166
177
|
end
|
178
|
+
ruby2_keywords(:method_missing)
|
179
|
+
|
180
|
+
def respond_to_missing?(name, _)
|
181
|
+
super || instance.respond_to?(name)
|
182
|
+
end
|
167
183
|
end
|
168
184
|
|
169
185
|
attr_accessor :attributes
|