activesupport 7.0.3.1 → 7.2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +261 -246
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +3 -1
- data/lib/active_support/backtrace_cleaner.rb +39 -7
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +51 -19
- data/lib/active_support/cache/mem_cache_store.rb +114 -134
- data/lib/active_support/cache/memory_store.rb +85 -30
- data/lib/active_support/cache/null_store.rb +8 -2
- data/lib/active_support/cache/redis_cache_store.rb +175 -154
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +64 -13
- data/lib/active_support/cache.rb +455 -378
- data/lib/active_support/callbacks.rb +121 -136
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +1 -2
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +1 -0
- data/lib/active_support/core_ext/class/attribute.rb +2 -2
- data/lib/active_support/core_ext/class/subclasses.rb +17 -34
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/calculations.rb +15 -0
- data/lib/active_support/core_ext/date/conversions.rb +1 -2
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -4
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +7 -10
- data/lib/active_support/core_ext/enumerable.rb +25 -80
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +7 -7
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -119
- data/lib/active_support/core_ext/module/deprecation.rb +12 -12
- data/lib/active_support/core_ext/module/introspection.rb +3 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/duplicable.rb +25 -16
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
- data/lib/active_support/core_ext/object/json.rb +17 -7
- data/lib/active_support/core_ext/object/to_query.rb +0 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +2 -2
- data/lib/active_support/core_ext/securerandom.rb +24 -12
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -9
- data/lib/active_support/core_ext/string/multibyte.rb +3 -3
- data/lib/active_support/core_ext/string/output_safety.rb +41 -178
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +40 -30
- data/lib/active_support/core_ext/time/compatibility.rb +24 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -3
- data/lib/active_support/core_ext/time/zones.rb +7 -8
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +60 -46
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +9 -16
- data/lib/active_support/deprecation/behaviors.rb +64 -41
- data/lib/active_support/deprecation/constant_accessor.rb +47 -25
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
- data/lib/active_support/deprecation/reporting.rb +49 -27
- data/lib/active_support/deprecation.rb +39 -9
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +66 -172
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -4
- data/lib/active_support/duration.rb +13 -7
- data/lib/active_support/encrypted_configuration.rb +63 -11
- data/lib/active_support/encrypted_file.rb +29 -13
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +163 -36
- data/lib/active_support/evented_file_update_checker.rb +17 -3
- data/lib/active_support/execution_wrapper.rb +5 -6
- data/lib/active_support/file_update_checker.rb +6 -4
- data/lib/active_support/fork_tracker.rb +4 -32
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +50 -30
- data/lib/active_support/html_safe_translation.rb +19 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +28 -18
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +3 -2
- data/lib/active_support/json/encoding.rb +48 -48
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +22 -7
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +74 -34
- data/lib/active_support/logger.rb +22 -59
- data/lib/active_support/logger_thread_safe_level.rb +10 -32
- data/lib/active_support/message_encryptor.rb +197 -53
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +305 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +229 -89
- data/lib/active_support/message_verifiers.rb +137 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +38 -31
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +8 -3
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +248 -87
- data/lib/active_support/notifications/instrumenter.rb +93 -25
- data/lib/active_support/notifications.rb +36 -29
- data/lib/active_support/number_helper/number_converter.rb +16 -7
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +17 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -317
- data/lib/active_support/option_merger.rb +4 -4
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +67 -15
- data/lib/active_support/parameter_filter.rb +103 -84
- data/lib/active_support/proxy_object.rb +8 -3
- data/lib/active_support/railtie.rb +25 -20
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +10 -8
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +10 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -40
- data/lib/active_support/test_case.rb +160 -7
- data/lib/active_support/testing/assertions.rb +28 -12
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +20 -27
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +46 -33
- data/lib/active_support/testing/method_call_assertions.rb +7 -8
- data/lib/active_support/testing/parallelization/server.rb +18 -2
- data/lib/active_support/testing/parallelization/worker.rb +2 -2
- data/lib/active_support/testing/parallelization.rb +12 -1
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +38 -16
- data/lib/active_support/time_with_zone.rb +18 -44
- data/lib/active_support/values/time_zone.rb +25 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- 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 +14 -3
- data/lib/active_support.rb +15 -3
- metadata +148 -24
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/deprecation/instance_delegator.rb +0 -38
- data/lib/active_support/per_thread_registry.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
|
@@ -16,7 +16,7 @@ class Object
|
|
|
16
16
|
#
|
|
17
17
|
# @return [true, false]
|
|
18
18
|
def blank?
|
|
19
|
-
respond_to?(:empty?) ? !!empty? :
|
|
19
|
+
respond_to?(:empty?) ? !!empty? : false
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# An object is present if it's not blank.
|
|
@@ -56,6 +56,10 @@ class NilClass
|
|
|
56
56
|
def blank?
|
|
57
57
|
true
|
|
58
58
|
end
|
|
59
|
+
|
|
60
|
+
def present? # :nodoc:
|
|
61
|
+
false
|
|
62
|
+
end
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
class FalseClass
|
|
@@ -67,6 +71,10 @@ class FalseClass
|
|
|
67
71
|
def blank?
|
|
68
72
|
true
|
|
69
73
|
end
|
|
74
|
+
|
|
75
|
+
def present? # :nodoc:
|
|
76
|
+
false
|
|
77
|
+
end
|
|
70
78
|
end
|
|
71
79
|
|
|
72
80
|
class TrueClass
|
|
@@ -78,6 +86,10 @@ class TrueClass
|
|
|
78
86
|
def blank?
|
|
79
87
|
false
|
|
80
88
|
end
|
|
89
|
+
|
|
90
|
+
def present? # :nodoc:
|
|
91
|
+
true
|
|
92
|
+
end
|
|
81
93
|
end
|
|
82
94
|
|
|
83
95
|
class Array
|
|
@@ -88,6 +100,10 @@ class Array
|
|
|
88
100
|
#
|
|
89
101
|
# @return [true, false]
|
|
90
102
|
alias_method :blank?, :empty?
|
|
103
|
+
|
|
104
|
+
def present? # :nodoc:
|
|
105
|
+
!empty?
|
|
106
|
+
end
|
|
91
107
|
end
|
|
92
108
|
|
|
93
109
|
class Hash
|
|
@@ -98,6 +114,22 @@ class Hash
|
|
|
98
114
|
#
|
|
99
115
|
# @return [true, false]
|
|
100
116
|
alias_method :blank?, :empty?
|
|
117
|
+
|
|
118
|
+
def present? # :nodoc:
|
|
119
|
+
!empty?
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class Symbol
|
|
124
|
+
# A Symbol is blank if it's empty:
|
|
125
|
+
#
|
|
126
|
+
# :''.blank? # => true
|
|
127
|
+
# :symbol.blank? # => false
|
|
128
|
+
alias_method :blank?, :empty?
|
|
129
|
+
|
|
130
|
+
def present? # :nodoc:
|
|
131
|
+
!empty?
|
|
132
|
+
end
|
|
101
133
|
end
|
|
102
134
|
|
|
103
135
|
class String
|
|
@@ -129,6 +161,10 @@ class String
|
|
|
129
161
|
ENCODED_BLANKS[self.encoding].match?(self)
|
|
130
162
|
end
|
|
131
163
|
end
|
|
164
|
+
|
|
165
|
+
def present? # :nodoc:
|
|
166
|
+
!blank?
|
|
167
|
+
end
|
|
132
168
|
end
|
|
133
169
|
|
|
134
170
|
class Numeric # :nodoc:
|
|
@@ -141,6 +177,10 @@ class Numeric # :nodoc:
|
|
|
141
177
|
def blank?
|
|
142
178
|
false
|
|
143
179
|
end
|
|
180
|
+
|
|
181
|
+
def present?
|
|
182
|
+
true
|
|
183
|
+
end
|
|
144
184
|
end
|
|
145
185
|
|
|
146
186
|
class Time # :nodoc:
|
|
@@ -152,4 +192,8 @@ class Time # :nodoc:
|
|
|
152
192
|
def blank?
|
|
153
193
|
false
|
|
154
194
|
end
|
|
195
|
+
|
|
196
|
+
def present?
|
|
197
|
+
true
|
|
198
|
+
end
|
|
155
199
|
end
|
|
@@ -53,3 +53,19 @@ class Hash
|
|
|
53
53
|
hash
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
|
+
|
|
57
|
+
class Module
|
|
58
|
+
# Returns a copy of module or class if it's anonymous. If it's
|
|
59
|
+
# named, returns +self+.
|
|
60
|
+
#
|
|
61
|
+
# Object.deep_dup == Object # => true
|
|
62
|
+
# klass = Class.new
|
|
63
|
+
# klass.deep_dup == klass # => false
|
|
64
|
+
def deep_dup
|
|
65
|
+
if name.nil?
|
|
66
|
+
super
|
|
67
|
+
else
|
|
68
|
+
self
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -28,23 +28,32 @@ class Object
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def duplicable?
|
|
37
|
-
false
|
|
38
|
-
end
|
|
31
|
+
methods_are_duplicable = begin
|
|
32
|
+
Object.instance_method(:duplicable?).dup
|
|
33
|
+
true
|
|
34
|
+
rescue TypeError
|
|
35
|
+
false
|
|
39
36
|
end
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
unless methods_are_duplicable
|
|
39
|
+
class Method
|
|
40
|
+
# Methods are not duplicable:
|
|
41
|
+
#
|
|
42
|
+
# method(:puts).duplicable? # => false
|
|
43
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
|
44
|
+
def duplicable?
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class UnboundMethod
|
|
50
|
+
# Unbound methods are not duplicable:
|
|
51
|
+
#
|
|
52
|
+
# method(:puts).unbind.duplicable? # => false
|
|
53
|
+
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
|
54
|
+
def duplicable?
|
|
55
|
+
false
|
|
56
|
+
end
|
|
48
57
|
end
|
|
49
58
|
end
|
|
50
59
|
|
|
@@ -53,7 +62,7 @@ require "singleton"
|
|
|
53
62
|
module Singleton
|
|
54
63
|
# Singleton instances are not duplicable:
|
|
55
64
|
#
|
|
56
|
-
#
|
|
65
|
+
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
|
57
66
|
def duplicable?
|
|
58
67
|
false
|
|
59
68
|
end
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Object
|
|
4
|
-
# Returns true if this object is included in the argument.
|
|
5
|
-
#
|
|
4
|
+
# Returns true if this object is included in the argument.
|
|
5
|
+
#
|
|
6
|
+
# When argument is a +Range+, +#cover?+ is used to properly handle inclusion
|
|
7
|
+
# check within open ranges. Otherwise, argument must be any object which responds
|
|
8
|
+
# to +#include?+. Usage:
|
|
6
9
|
#
|
|
7
10
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
|
8
11
|
# "Konata".in?(characters) # => true
|
|
9
12
|
#
|
|
10
|
-
#
|
|
11
|
-
# to +#include?+.
|
|
13
|
+
# For non +Range+ arguments, this will throw an +ArgumentError+ if the argument
|
|
14
|
+
# doesn't respond to +#include?+.
|
|
12
15
|
def in?(another_object)
|
|
13
|
-
another_object
|
|
16
|
+
case another_object
|
|
17
|
+
when Range
|
|
18
|
+
another_object.cover?(self)
|
|
19
|
+
else
|
|
20
|
+
another_object.include?(self)
|
|
21
|
+
end
|
|
14
22
|
rescue NoMethodError
|
|
15
23
|
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
|
|
16
24
|
end
|
|
@@ -12,7 +12,9 @@ class Object
|
|
|
12
12
|
#
|
|
13
13
|
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
|
14
14
|
def instance_values
|
|
15
|
-
|
|
15
|
+
instance_variables.to_h do |ivar|
|
|
16
|
+
[ivar[1..-1].freeze, instance_variable_get(ivar)]
|
|
17
|
+
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
# Returns an array of instance variable names as strings including "@".
|
|
@@ -25,6 +27,6 @@ class Object
|
|
|
25
27
|
#
|
|
26
28
|
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
|
27
29
|
def instance_variable_names
|
|
28
|
-
instance_variables.map(&:
|
|
30
|
+
instance_variables.map(&:name)
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Hack to load
|
|
3
|
+
# Hack to load JSON gem first so we can override its to_json.
|
|
4
4
|
require "json"
|
|
5
5
|
require "bigdecimal"
|
|
6
6
|
require "ipaddr"
|
|
@@ -29,7 +29,7 @@ require "active_support/core_ext/date/conversions"
|
|
|
29
29
|
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
|
|
30
30
|
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
|
31
31
|
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
|
32
|
-
# should give exactly the same results with or without
|
|
32
|
+
# should give exactly the same results with or without Active Support.
|
|
33
33
|
|
|
34
34
|
module ActiveSupport
|
|
35
35
|
module ToJsonWithActiveSupportEncoder # :nodoc:
|
|
@@ -46,7 +46,7 @@ module ActiveSupport
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
|
|
49
|
-
klass.
|
|
49
|
+
klass.include(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
class Module
|
|
@@ -65,9 +65,17 @@ class Object
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
if RUBY_VERSION >= "3.2"
|
|
69
|
+
class Data # :nodoc:
|
|
70
|
+
def as_json(options = nil)
|
|
71
|
+
to_h.as_json(options)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
68
76
|
class Struct # :nodoc:
|
|
69
77
|
def as_json(options = nil)
|
|
70
|
-
|
|
78
|
+
to_h.as_json(options)
|
|
71
79
|
end
|
|
72
80
|
end
|
|
73
81
|
|
|
@@ -225,9 +233,11 @@ class Pathname # :nodoc:
|
|
|
225
233
|
end
|
|
226
234
|
end
|
|
227
235
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
236
|
+
unless IPAddr.method_defined?(:as_json, false)
|
|
237
|
+
class IPAddr # :nodoc:
|
|
238
|
+
def as_json(options = nil)
|
|
239
|
+
to_s
|
|
240
|
+
end
|
|
231
241
|
end
|
|
232
242
|
end
|
|
233
243
|
|
|
@@ -72,8 +72,6 @@ class Hash
|
|
|
72
72
|
#
|
|
73
73
|
# The string pairs "key=value" that conform the query string
|
|
74
74
|
# are sorted lexicographically in ascending order.
|
|
75
|
-
#
|
|
76
|
-
# This method is also aliased as +to_param+.
|
|
77
75
|
def to_query(namespace = nil)
|
|
78
76
|
query = filter_map do |key, value|
|
|
79
77
|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
|
@@ -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
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Object
|
|
4
|
+
# Set and restore public attributes around a block.
|
|
5
|
+
#
|
|
6
|
+
# client.timeout # => 5
|
|
7
|
+
# client.with(timeout: 1) do |c|
|
|
8
|
+
# c.timeout # => 1
|
|
9
|
+
# end
|
|
10
|
+
# client.timeout # => 5
|
|
11
|
+
#
|
|
12
|
+
# The receiver is yielded to the provided block.
|
|
13
|
+
#
|
|
14
|
+
# This method is a shorthand for the common begin/ensure pattern:
|
|
15
|
+
#
|
|
16
|
+
# old_value = object.attribute
|
|
17
|
+
# begin
|
|
18
|
+
# object.attribute = new_value
|
|
19
|
+
# # do things
|
|
20
|
+
# ensure
|
|
21
|
+
# object.attribute = old_value
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# It can be used on any object as long as both the reader and writer methods
|
|
25
|
+
# are public.
|
|
26
|
+
def with(**attributes)
|
|
27
|
+
old_values = {}
|
|
28
|
+
begin
|
|
29
|
+
attributes.each do |key, value|
|
|
30
|
+
old_values[key] = public_send(key)
|
|
31
|
+
public_send("#{key}=", value)
|
|
32
|
+
end
|
|
33
|
+
yield self
|
|
34
|
+
ensure
|
|
35
|
+
old_values.each do |key, old_value|
|
|
36
|
+
public_send("#{key}=", old_value)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# #with isn't usable on immediates, so we might as well undefine the
|
|
43
|
+
# method in common immediate classes to avoid potential confusion.
|
|
44
|
+
[NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass|
|
|
45
|
+
klass.undef_method(:with)
|
|
46
|
+
end
|
|
@@ -5,9 +5,9 @@ require "active_support/option_merger"
|
|
|
5
5
|
class Object
|
|
6
6
|
# An elegant way to factor duplication out of options passed to a series of
|
|
7
7
|
# method calls. Each method called in the block, with the block variable as
|
|
8
|
-
# the receiver, will have its options merged with the default +options+
|
|
9
|
-
# provided. Each method called on
|
|
10
|
-
# hash as its final argument.
|
|
8
|
+
# the receiver, will have its options merged with the default +options+
|
|
9
|
+
# <tt>Hash</tt> or <tt>Hash</tt>-like object provided. Each method called on
|
|
10
|
+
# the block variable must take an options hash as its final argument.
|
|
11
11
|
#
|
|
12
12
|
# Without <tt>with_options</tt>, this code contains duplication:
|
|
13
13
|
#
|
|
@@ -64,11 +64,11 @@ class Object
|
|
|
64
64
|
#
|
|
65
65
|
# Hence the inherited default for +if+ key is ignored.
|
|
66
66
|
#
|
|
67
|
-
# NOTE: You cannot call class methods implicitly inside of with_options
|
|
67
|
+
# NOTE: You cannot call class methods implicitly inside of +with_options+.
|
|
68
68
|
# You can access these methods using the class name instead:
|
|
69
69
|
#
|
|
70
70
|
# class Phone < ActiveRecord::Base
|
|
71
|
-
# enum phone_number_type
|
|
71
|
+
# enum :phone_number_type, { home: 0, office: 1, mobile: 2 }
|
|
72
72
|
#
|
|
73
73
|
# with_options presence: true do
|
|
74
74
|
# validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
|
|
@@ -83,11 +83,11 @@ class Object
|
|
|
83
83
|
# end
|
|
84
84
|
# end
|
|
85
85
|
#
|
|
86
|
-
#
|
|
87
|
-
# #
|
|
86
|
+
# styled.link_to "I'm red", "/"
|
|
87
|
+
# # => <a href="/" style="color: red;">I'm red</a>
|
|
88
88
|
#
|
|
89
|
-
#
|
|
90
|
-
# #
|
|
89
|
+
# styled.button_tag "I'm red too!"
|
|
90
|
+
# # => <button style="color: red;">I'm red too!</button>
|
|
91
91
|
#
|
|
92
92
|
def with_options(options, &block)
|
|
93
93
|
option_merger = ActiveSupport::OptionMerger.new(self, options)
|
|
@@ -13,4 +13,5 @@ require "active_support/core_ext/object/instance_variables"
|
|
|
13
13
|
require "active_support/core_ext/object/json"
|
|
14
14
|
require "active_support/core_ext/object/to_param"
|
|
15
15
|
require "active_support/core_ext/object/to_query"
|
|
16
|
+
require "active_support/core_ext/object/with"
|
|
16
17
|
require "active_support/core_ext/object/with_options"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pathname"
|
|
4
|
+
|
|
5
|
+
class Pathname
|
|
6
|
+
# An Pathname is blank if it's empty:
|
|
7
|
+
#
|
|
8
|
+
# Pathname.new("").blank? # => true
|
|
9
|
+
# Pathname.new(" ").blank? # => false
|
|
10
|
+
# Pathname.new("test").blank? # => false
|
|
11
|
+
#
|
|
12
|
+
# @return [true, false]
|
|
13
|
+
def blank?
|
|
14
|
+
to_s.empty?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def present? # :nodoc:
|
|
18
|
+
!to_s.empty?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ActiveSupport
|
|
4
|
+
# = \Range With Format
|
|
4
5
|
module RangeWithFormat
|
|
5
6
|
RANGE_FORMATS = {
|
|
6
7
|
db: -> (start, stop) do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
if start && stop
|
|
9
|
+
case start
|
|
10
|
+
when String then "BETWEEN '#{start}' AND '#{stop}'"
|
|
11
|
+
else
|
|
12
|
+
"BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
|
|
13
|
+
end
|
|
14
|
+
elsif start
|
|
15
|
+
case start
|
|
16
|
+
when String then ">= '#{start}'"
|
|
17
|
+
else
|
|
18
|
+
">= '#{start.to_fs(:db)}'"
|
|
19
|
+
end
|
|
20
|
+
elsif stop
|
|
21
|
+
case stop
|
|
22
|
+
when String then "<= '#{stop}'"
|
|
23
|
+
else
|
|
24
|
+
"<= '#{stop.to_fs(:db)}'"
|
|
25
|
+
end
|
|
11
26
|
end
|
|
12
27
|
end
|
|
13
28
|
}
|
|
@@ -19,9 +34,15 @@ module ActiveSupport
|
|
|
19
34
|
# range = (1..100) # => 1..100
|
|
20
35
|
#
|
|
21
36
|
# range.to_s # => "1..100"
|
|
22
|
-
# range.to_fs(:db)
|
|
37
|
+
# range.to_fs(:db) # => "BETWEEN '1' AND '100'"
|
|
23
38
|
#
|
|
24
|
-
#
|
|
39
|
+
# range = (1..) # => 1..
|
|
40
|
+
# range.to_fs(:db) # => ">= '1'"
|
|
41
|
+
#
|
|
42
|
+
# range = (..100) # => ..100
|
|
43
|
+
# range.to_fs(:db) # => "<= '100'"
|
|
44
|
+
#
|
|
45
|
+
# == Adding your own range formats to to_fs
|
|
25
46
|
# You can add your own formats to the Range::RANGE_FORMATS hash.
|
|
26
47
|
# Use the format name as the hash key and a Proc instance.
|
|
27
48
|
#
|
|
@@ -29,7 +50,7 @@ module ActiveSupport
|
|
|
29
50
|
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
|
|
30
51
|
def to_fs(format = :default)
|
|
31
52
|
if formatter = RANGE_FORMATS[format]
|
|
32
|
-
formatter.call(
|
|
53
|
+
formatter.call(self.begin, self.end)
|
|
33
54
|
else
|
|
34
55
|
to_s
|
|
35
56
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Range
|
|
4
|
+
# Compare two ranges and see if they overlap each other
|
|
5
|
+
# (1..5).overlap?(4..6) # => true
|
|
6
|
+
# (1..5).overlap?(7..9) # => false
|
|
7
|
+
unless Range.method_defined?(:overlap?) # Ruby 3.3+
|
|
8
|
+
def overlap?(other)
|
|
9
|
+
raise TypeError unless other.is_a? Range
|
|
10
|
+
|
|
11
|
+
self_begin = self.begin
|
|
12
|
+
other_end = other.end
|
|
13
|
+
other_excl = other.exclude_end?
|
|
14
|
+
|
|
15
|
+
return false if _empty_range?(self_begin, other_end, other_excl)
|
|
16
|
+
|
|
17
|
+
other_begin = other.begin
|
|
18
|
+
self_end = self.end
|
|
19
|
+
self_excl = self.exclude_end?
|
|
20
|
+
|
|
21
|
+
return false if _empty_range?(other_begin, self_end, self_excl)
|
|
22
|
+
return true if self_begin == other_begin
|
|
23
|
+
|
|
24
|
+
return false if _empty_range?(self_begin, self_end, self_excl)
|
|
25
|
+
return false if _empty_range?(other_begin, other_end, other_excl)
|
|
26
|
+
|
|
27
|
+
true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
def _empty_range?(b, e, excl)
|
|
32
|
+
return false if b.nil? || e.nil?
|
|
33
|
+
|
|
34
|
+
comp = b <=> e
|
|
35
|
+
comp.nil? || comp > 0 || (comp == 0 && excl)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
alias :overlaps? :overlap?
|
|
40
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Range
|
|
4
|
+
# Returns the sole item in the range. If there are no items, or more
|
|
5
|
+
# than one item, raises Enumerable::SoleItemExpectedError.
|
|
6
|
+
#
|
|
7
|
+
# (1..1).sole # => 1
|
|
8
|
+
# (2..1).sole # => Enumerable::SoleItemExpectedError: no item found
|
|
9
|
+
# (..1).sole # => Enumerable::SoleItemExpectedError: infinite range cannot represent a sole item
|
|
10
|
+
def sole
|
|
11
|
+
if self.begin.nil? || self.end.nil?
|
|
12
|
+
raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "infinite range '#{inspect}' cannot represent a sole item"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/range/conversions"
|
|
4
|
-
require "active_support/core_ext/range/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
|
5
4
|
require "active_support/core_ext/range/compare_range"
|
|
6
|
-
require "active_support/core_ext/range/
|
|
5
|
+
require "active_support/core_ext/range/overlap"
|
|
7
6
|
require "active_support/core_ext/range/each"
|
|
7
|
+
require "active_support/core_ext/range/sole"
|
|
@@ -16,12 +16,18 @@ module SecureRandom
|
|
|
16
16
|
#
|
|
17
17
|
# p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
|
|
18
18
|
# p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version
|
|
20
|
+
def self.base58(n = 16)
|
|
21
|
+
alphanumeric(n, chars: BASE58_ALPHABET)
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
def self.base58(n = 16)
|
|
25
|
+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
|
|
26
|
+
idx = byte % 64
|
|
27
|
+
idx = SecureRandom.random_number(58) if idx >= 58
|
|
28
|
+
BASE58_ALPHABET[idx]
|
|
29
|
+
end.join
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
# SecureRandom.base36 generates a random base36 string in lowercase.
|
|
@@ -35,11 +41,17 @@ module SecureRandom
|
|
|
35
41
|
#
|
|
36
42
|
# p SecureRandom.base36 # => "4kugl2pdqmscqtje"
|
|
37
43
|
# p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version
|
|
45
|
+
def self.base36(n = 16)
|
|
46
|
+
alphanumeric(n, chars: BASE36_ALPHABET)
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
def self.base36(n = 16)
|
|
50
|
+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
|
|
51
|
+
idx = byte % 64
|
|
52
|
+
idx = SecureRandom.random_number(36) if idx >= 36
|
|
53
|
+
BASE36_ALPHABET[idx]
|
|
54
|
+
end.join
|
|
55
|
+
end
|
|
44
56
|
end
|
|
45
57
|
end
|
|
@@ -22,7 +22,7 @@ class String
|
|
|
22
22
|
def to_time(form = :local)
|
|
23
23
|
parts = Date._parse(self, false)
|
|
24
24
|
used_keys = %i(year mon mday hour min sec sec_fraction offset)
|
|
25
|
-
return if
|
|
25
|
+
return if !parts.keys.intersect?(used_keys)
|
|
26
26
|
|
|
27
27
|
now = Time.now
|
|
28
28
|
time = Time.new(
|