activesupport 5.2.4.3 → 7.0.3
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.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +244 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +47 -41
- data/lib/active_support/cache/mem_cache_store.rb +151 -40
- data/lib/active_support/cache/memory_store.rb +68 -34
- data/lib/active_support/cache/null_store.rb +16 -3
- data/lib/active_support/cache/redis_cache_store.rb +103 -101
- data/lib/active_support/cache/strategy/local_cache.rb +56 -64
- data/lib/active_support/cache.rb +333 -116
- data/lib/active_support/callbacks.rb +244 -128
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +72 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -3
- data/lib/active_support/configurable.rb +15 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +15 -7
- data/lib/active_support/core_ext/array/conversions.rb +18 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +2 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +32 -47
- data/lib/active_support/core_ext/class/subclasses.rb +9 -22
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +15 -14
- data/lib/active_support/core_ext/date/conversions.rb +16 -15
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -51
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +241 -76
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -31
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +32 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +35 -28
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +70 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +132 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -1
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +3 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +14 -110
- data/lib/active_support/core_ext/object/json.rb +44 -27
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +24 -14
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +23 -27
- data/lib/active_support/core_ext/range/conversions.rb +32 -30
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +8 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +46 -7
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +129 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +59 -10
- data/lib/active_support/core_ext/time/conversions.rb +15 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +7 -22
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -22
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +47 -16
- 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 +60 -715
- data/lib/active_support/deprecation/behaviors.rb +21 -5
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +31 -8
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +190 -34
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +5 -7
- data/lib/active_support/duration/iso8601_serializer.rb +27 -15
- data/lib/active_support/duration.rb +149 -67
- data/lib/active_support/encrypted_configuration.rb +12 -5
- data/lib/active_support/encrypted_file.rb +23 -5
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +85 -122
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +44 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +73 -43
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +2 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +25 -14
- data/lib/active_support/inflector/methods.rb +38 -71
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +14 -6
- data/lib/active_support/key_generator.rb +23 -38
- data/lib/active_support/lazy_load_hooks.rb +19 -5
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +51 -11
- data/lib/active_support/logger.rb +6 -22
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +45 -10
- data/lib/active_support/message_encryptor.rb +20 -19
- data/lib/active_support/message_verifier.rb +53 -21
- data/lib/active_support/messages/metadata.rb +13 -4
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +17 -76
- data/lib/active_support/multibyte/unicode.rb +7 -331
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +163 -37
- data/lib/active_support/notifications/instrumenter.rb +90 -11
- data/lib/active_support/notifications.rb +88 -30
- data/lib/active_support/number_helper/number_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +12 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +36 -12
- data/lib/active_support/option_merger.rb +15 -4
- data/lib/active_support/ordered_hash.rb +2 -2
- data/lib/active_support/ordered_options.rb +14 -4
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +5 -6
- data/lib/active_support/rescuable.rb +8 -8
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +2 -3
- data/lib/active_support/subscriber.rb +79 -46
- data/lib/active_support/tagged_logging.rb +58 -9
- data/lib/active_support/test_case.rb +79 -0
- data/lib/active_support/testing/assertions.rb +62 -11
- data/lib/active_support/testing/deprecation.rb +52 -2
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +4 -4
- data/lib/active_support/testing/method_call_assertions.rb +32 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +4 -7
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +60 -14
- data/lib/active_support/time_with_zone.rb +139 -64
- data/lib/active_support/values/time_zone.rb +66 -30
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -4
- data/lib/active_support/xml_mini/libxml.rb +7 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +5 -5
- data/lib/active_support/xml_mini/nokogiri.rb +6 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +4 -4
- data/lib/active_support/xml_mini/rexml.rb +11 -4
- data/lib/active_support/xml_mini.rb +7 -14
- data/lib/active_support.rb +30 -1
- metadata +64 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -28,93 +28,6 @@ class Object
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
class NilClass
|
32
|
-
begin
|
33
|
-
nil.dup
|
34
|
-
rescue TypeError
|
35
|
-
|
36
|
-
# +nil+ is not duplicable:
|
37
|
-
#
|
38
|
-
# nil.duplicable? # => false
|
39
|
-
# nil.dup # => TypeError: can't dup NilClass
|
40
|
-
def duplicable?
|
41
|
-
false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class FalseClass
|
47
|
-
begin
|
48
|
-
false.dup
|
49
|
-
rescue TypeError
|
50
|
-
|
51
|
-
# +false+ is not duplicable:
|
52
|
-
#
|
53
|
-
# false.duplicable? # => false
|
54
|
-
# false.dup # => TypeError: can't dup FalseClass
|
55
|
-
def duplicable?
|
56
|
-
false
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
class TrueClass
|
62
|
-
begin
|
63
|
-
true.dup
|
64
|
-
rescue TypeError
|
65
|
-
|
66
|
-
# +true+ is not duplicable:
|
67
|
-
#
|
68
|
-
# true.duplicable? # => false
|
69
|
-
# true.dup # => TypeError: can't dup TrueClass
|
70
|
-
def duplicable?
|
71
|
-
false
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
class Symbol
|
77
|
-
begin
|
78
|
-
:symbol.dup # Ruby 2.4.x.
|
79
|
-
"symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
|
80
|
-
rescue TypeError
|
81
|
-
|
82
|
-
# Symbols are not duplicable:
|
83
|
-
#
|
84
|
-
# :my_symbol.duplicable? # => false
|
85
|
-
# :my_symbol.dup # => TypeError: can't dup Symbol
|
86
|
-
def duplicable?
|
87
|
-
false
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class Numeric
|
93
|
-
begin
|
94
|
-
1.dup
|
95
|
-
rescue TypeError
|
96
|
-
|
97
|
-
# Numbers are not duplicable:
|
98
|
-
#
|
99
|
-
# 3.duplicable? # => false
|
100
|
-
# 3.dup # => TypeError: can't dup Integer
|
101
|
-
def duplicable?
|
102
|
-
false
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
require "bigdecimal"
|
108
|
-
class BigDecimal
|
109
|
-
# BigDecimals are duplicable:
|
110
|
-
#
|
111
|
-
# BigDecimal("1.2").duplicable? # => true
|
112
|
-
# BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
|
113
|
-
def duplicable?
|
114
|
-
true
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
31
|
class Method
|
119
32
|
# Methods are not duplicable:
|
120
33
|
#
|
@@ -125,32 +38,23 @@ class Method
|
|
125
38
|
end
|
126
39
|
end
|
127
40
|
|
128
|
-
class
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# Complex(1).duplicable? # => false
|
136
|
-
# Complex(1).dup # => TypeError: can't copy Complex
|
137
|
-
def duplicable?
|
138
|
-
false
|
139
|
-
end
|
41
|
+
class UnboundMethod
|
42
|
+
# Unbound methods are not duplicable:
|
43
|
+
#
|
44
|
+
# method(:puts).unbind.duplicable? # => false
|
45
|
+
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
46
|
+
def duplicable?
|
47
|
+
false
|
140
48
|
end
|
141
49
|
end
|
142
50
|
|
143
|
-
|
144
|
-
begin
|
145
|
-
Rational(1).dup
|
146
|
-
rescue TypeError
|
51
|
+
require "singleton"
|
147
52
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
end
|
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
|
155
59
|
end
|
156
60
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Hack to load json gem first so we can
|
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
|
@@ -14,11 +15,11 @@ require "active_support/core_ext/time/conversions"
|
|
14
15
|
require "active_support/core_ext/date_time/conversions"
|
15
16
|
require "active_support/core_ext/date/conversions"
|
16
17
|
|
18
|
+
#--
|
17
19
|
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
18
20
|
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
19
21
|
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
20
|
-
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
|
21
|
-
# 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.
|
22
23
|
#
|
23
24
|
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
24
25
|
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
@@ -44,12 +45,18 @@ module ActiveSupport
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass
|
48
|
+
[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
|
48
49
|
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
49
50
|
end
|
50
51
|
|
52
|
+
class Module
|
53
|
+
def as_json(options = nil) # :nodoc:
|
54
|
+
name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
51
58
|
class Object
|
52
|
-
def as_json(options = nil)
|
59
|
+
def as_json(options = nil) # :nodoc:
|
53
60
|
if respond_to?(:to_hash)
|
54
61
|
to_hash.as_json(options)
|
55
62
|
else
|
@@ -58,44 +65,44 @@ class Object
|
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
61
|
-
class Struct
|
68
|
+
class Struct # :nodoc:
|
62
69
|
def as_json(options = nil)
|
63
70
|
Hash[members.zip(values)].as_json(options)
|
64
71
|
end
|
65
72
|
end
|
66
73
|
|
67
74
|
class TrueClass
|
68
|
-
def as_json(options = nil)
|
75
|
+
def as_json(options = nil) # :nodoc:
|
69
76
|
self
|
70
77
|
end
|
71
78
|
end
|
72
79
|
|
73
80
|
class FalseClass
|
74
|
-
def as_json(options = nil)
|
81
|
+
def as_json(options = nil) # :nodoc:
|
75
82
|
self
|
76
83
|
end
|
77
84
|
end
|
78
85
|
|
79
86
|
class NilClass
|
80
|
-
def as_json(options = nil)
|
87
|
+
def as_json(options = nil) # :nodoc:
|
81
88
|
self
|
82
89
|
end
|
83
90
|
end
|
84
91
|
|
85
92
|
class String
|
86
|
-
def as_json(options = nil)
|
93
|
+
def as_json(options = nil) # :nodoc:
|
87
94
|
self
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
91
98
|
class Symbol
|
92
|
-
def as_json(options = nil)
|
99
|
+
def as_json(options = nil) # :nodoc:
|
93
100
|
to_s
|
94
101
|
end
|
95
102
|
end
|
96
103
|
|
97
104
|
class Numeric
|
98
|
-
def as_json(options = nil)
|
105
|
+
def as_json(options = nil) # :nodoc:
|
99
106
|
self
|
100
107
|
end
|
101
108
|
end
|
@@ -103,7 +110,7 @@ end
|
|
103
110
|
class Float
|
104
111
|
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
105
112
|
# "Infinity" or "NaN" which are not valid JSON.
|
106
|
-
def as_json(options = nil)
|
113
|
+
def as_json(options = nil) # :nodoc:
|
107
114
|
finite? ? self : nil
|
108
115
|
end
|
109
116
|
end
|
@@ -118,43 +125,43 @@ class BigDecimal
|
|
118
125
|
# if the other end knows by contract that the data is supposed to be a
|
119
126
|
# BigDecimal, it still has the chance to post-process the string and get the
|
120
127
|
# real value.
|
121
|
-
def as_json(options = nil)
|
128
|
+
def as_json(options = nil) # :nodoc:
|
122
129
|
finite? ? to_s : nil
|
123
130
|
end
|
124
131
|
end
|
125
132
|
|
126
133
|
class Regexp
|
127
|
-
def as_json(options = nil)
|
134
|
+
def as_json(options = nil) # :nodoc:
|
128
135
|
to_s
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
132
139
|
module Enumerable
|
133
|
-
def as_json(options = nil)
|
140
|
+
def as_json(options = nil) # :nodoc:
|
134
141
|
to_a.as_json(options)
|
135
142
|
end
|
136
143
|
end
|
137
144
|
|
138
145
|
class IO
|
139
|
-
def as_json(options = nil)
|
146
|
+
def as_json(options = nil) # :nodoc:
|
140
147
|
to_s
|
141
148
|
end
|
142
149
|
end
|
143
150
|
|
144
151
|
class Range
|
145
|
-
def as_json(options = nil)
|
152
|
+
def as_json(options = nil) # :nodoc:
|
146
153
|
to_s
|
147
154
|
end
|
148
155
|
end
|
149
156
|
|
150
157
|
class Array
|
151
|
-
def as_json(options = nil)
|
158
|
+
def as_json(options = nil) # :nodoc:
|
152
159
|
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
153
160
|
end
|
154
161
|
end
|
155
162
|
|
156
163
|
class Hash
|
157
|
-
def as_json(options = nil)
|
164
|
+
def as_json(options = nil) # :nodoc:
|
158
165
|
# create a subset of the hash by applying :only or :except
|
159
166
|
subset = if options
|
160
167
|
if attrs = options[:only]
|
@@ -168,12 +175,16 @@ class Hash
|
|
168
175
|
self
|
169
176
|
end
|
170
177
|
|
171
|
-
|
178
|
+
result = {}
|
179
|
+
subset.each do |k, v|
|
180
|
+
result[k.to_s] = options ? v.as_json(options.dup) : v.as_json
|
181
|
+
end
|
182
|
+
result
|
172
183
|
end
|
173
184
|
end
|
174
185
|
|
175
186
|
class Time
|
176
|
-
def as_json(options = nil)
|
187
|
+
def as_json(options = nil) # :nodoc:
|
177
188
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
178
189
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
179
190
|
else
|
@@ -183,7 +194,7 @@ class Time
|
|
183
194
|
end
|
184
195
|
|
185
196
|
class Date
|
186
|
-
def as_json(options = nil)
|
197
|
+
def as_json(options = nil) # :nodoc:
|
187
198
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
188
199
|
strftime("%Y-%m-%d")
|
189
200
|
else
|
@@ -193,7 +204,7 @@ class Date
|
|
193
204
|
end
|
194
205
|
|
195
206
|
class DateTime
|
196
|
-
def as_json(options = nil)
|
207
|
+
def as_json(options = nil) # :nodoc:
|
197
208
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
198
209
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
199
210
|
else
|
@@ -202,19 +213,25 @@ class DateTime
|
|
202
213
|
end
|
203
214
|
end
|
204
215
|
|
205
|
-
class URI::Generic
|
216
|
+
class URI::Generic # :nodoc:
|
217
|
+
def as_json(options = nil)
|
218
|
+
to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class Pathname # :nodoc:
|
206
223
|
def as_json(options = nil)
|
207
224
|
to_s
|
208
225
|
end
|
209
226
|
end
|
210
227
|
|
211
|
-
class
|
228
|
+
class IPAddr # :nodoc:
|
212
229
|
def as_json(options = nil)
|
213
230
|
to_s
|
214
231
|
end
|
215
232
|
end
|
216
233
|
|
217
|
-
class Process::Status
|
234
|
+
class Process::Status # :nodoc:
|
218
235
|
def as_json(options = nil)
|
219
236
|
{ exitstatus: exitstatus, pid: pid }
|
220
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,22 +3,32 @@
|
|
3
3
|
require "delegate"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
module Tryable
|
7
|
-
def try(*
|
8
|
-
|
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
|
+
else
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
elsif respond_to?(args.first)
|
15
|
+
public_send(*args, &block)
|
16
|
+
end
|
9
17
|
end
|
18
|
+
ruby2_keywords(:try)
|
10
19
|
|
11
|
-
def try!(*
|
12
|
-
if
|
13
|
-
if
|
14
|
-
instance_eval(&
|
20
|
+
def try!(*args, &block)
|
21
|
+
if args.empty? && block_given?
|
22
|
+
if block.arity == 0
|
23
|
+
instance_eval(&block)
|
15
24
|
else
|
16
25
|
yield self
|
17
26
|
end
|
18
27
|
else
|
19
|
-
public_send(*
|
28
|
+
public_send(*args, &block)
|
20
29
|
end
|
21
30
|
end
|
31
|
+
ruby2_keywords(:try!)
|
22
32
|
end
|
23
33
|
end
|
24
34
|
|
@@ -29,7 +39,7 @@ class Object
|
|
29
39
|
# :method: try
|
30
40
|
#
|
31
41
|
# :call-seq:
|
32
|
-
# try(*
|
42
|
+
# try(*args, &block)
|
33
43
|
#
|
34
44
|
# Invokes the public method whose name goes as first argument just like
|
35
45
|
# +public_send+ does, except that if the receiver does not respond to it the
|
@@ -94,7 +104,7 @@ class Object
|
|
94
104
|
# :method: try!
|
95
105
|
#
|
96
106
|
# :call-seq:
|
97
|
-
# try!(*
|
107
|
+
# try!(*args, &block)
|
98
108
|
#
|
99
109
|
# Same as #try, but raises a +NoMethodError+ exception if the receiver is
|
100
110
|
# not +nil+ and does not implement the tried method.
|
@@ -111,7 +121,7 @@ class Delegator
|
|
111
121
|
# :method: try
|
112
122
|
#
|
113
123
|
# :call-seq:
|
114
|
-
# try(
|
124
|
+
# try(*args, &block)
|
115
125
|
#
|
116
126
|
# See Object#try
|
117
127
|
|
@@ -119,7 +129,7 @@ class Delegator
|
|
119
129
|
# :method: try!
|
120
130
|
#
|
121
131
|
# :call-seq:
|
122
|
-
# try!(
|
132
|
+
# try!(*args, &block)
|
123
133
|
#
|
124
134
|
# See Object#try!
|
125
135
|
end
|
@@ -135,14 +145,14 @@ class NilClass
|
|
135
145
|
#
|
136
146
|
# With +try+
|
137
147
|
# @person.try(:children).try(:first).try(:name)
|
138
|
-
def try(*
|
148
|
+
def try(*)
|
139
149
|
nil
|
140
150
|
end
|
141
151
|
|
142
152
|
# Calling +try!+ on +nil+ always returns +nil+.
|
143
153
|
#
|
144
154
|
# nil.try!(:name) # => nil
|
145
|
-
def try!(*
|
155
|
+
def try!(*)
|
146
156
|
nil
|
147
157
|
end
|
148
158
|
end
|
@@ -68,15 +68,34 @@ class Object
|
|
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 }
|
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
|
-
|
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
|
@@ -1,56 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
|
-
module CompareWithRange
|
4
|
+
module CompareWithRange
|
5
5
|
# Extends the default Range#=== to support range comparisons.
|
6
|
-
# (1..5) === (1..5)
|
7
|
-
# (1..5) === (2..3)
|
8
|
-
# (1..5) === (
|
6
|
+
# (1..5) === (1..5) # => true
|
7
|
+
# (1..5) === (2..3) # => true
|
8
|
+
# (1..5) === (1...6) # => true
|
9
|
+
# (1..5) === (2..6) # => false
|
9
10
|
#
|
10
11
|
# The native Range#=== behavior is untouched.
|
11
12
|
# ('a'..'f') === ('c') # => true
|
12
13
|
# (5..9) === (11) # => false
|
14
|
+
#
|
15
|
+
# The given range must be fully bounded, with both start and end.
|
13
16
|
def ===(value)
|
14
17
|
if value.is_a?(::Range)
|
18
|
+
is_backwards_op = value.exclude_end? ? :>= : :>
|
19
|
+
return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
|
15
20
|
# 1...10 includes 1..9 but it does not include 1..10.
|
21
|
+
# 1..10 includes 1...11 but it does not include 1...12.
|
16
22
|
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
17
|
-
|
23
|
+
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
|
24
|
+
super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
|
18
25
|
else
|
19
26
|
super
|
20
27
|
end
|
21
28
|
end
|
22
29
|
|
23
30
|
# Extends the default Range#include? to support range comparisons.
|
24
|
-
# (1..5).include?(1..5)
|
25
|
-
# (1..5).include?(2..3)
|
26
|
-
# (1..5).include?(
|
31
|
+
# (1..5).include?(1..5) # => true
|
32
|
+
# (1..5).include?(2..3) # => true
|
33
|
+
# (1..5).include?(1...6) # => true
|
34
|
+
# (1..5).include?(2..6) # => false
|
27
35
|
#
|
28
36
|
# The native Range#include? behavior is untouched.
|
29
37
|
# ('a'..'f').include?('c') # => true
|
30
38
|
# (5..9).include?(11) # => false
|
39
|
+
#
|
40
|
+
# The given range must be fully bounded, with both start and end.
|
31
41
|
def include?(value)
|
32
42
|
if value.is_a?(::Range)
|
43
|
+
is_backwards_op = value.exclude_end? ? :>= : :>
|
44
|
+
return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
|
33
45
|
# 1...10 includes 1..9 but it does not include 1..10.
|
46
|
+
# 1..10 includes 1...11 but it does not include 1...12.
|
34
47
|
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
35
|
-
|
36
|
-
|
37
|
-
super
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Extends the default Range#cover? to support range comparisons.
|
42
|
-
# (1..5).cover?(1..5) # => true
|
43
|
-
# (1..5).cover?(2..3) # => true
|
44
|
-
# (1..5).cover?(2..6) # => false
|
45
|
-
#
|
46
|
-
# The native Range#cover? behavior is untouched.
|
47
|
-
# ('a'..'f').cover?('c') # => true
|
48
|
-
# (5..9).cover?(11) # => false
|
49
|
-
def cover?(value)
|
50
|
-
if value.is_a?(::Range)
|
51
|
-
# 1...10 covers 1..9 but it does not cover 1..10.
|
52
|
-
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
53
|
-
super(value.first) && value.last.send(operator, last)
|
48
|
+
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
|
49
|
+
super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
|
54
50
|
else
|
55
51
|
super
|
56
52
|
end
|
@@ -1,39 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module ActiveSupport
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module ActiveSupport
|
4
|
+
module RangeWithFormat
|
5
|
+
RANGE_FORMATS = {
|
6
|
+
db: -> (start, stop) do
|
7
|
+
case start
|
8
|
+
when String then "BETWEEN '#{start}' AND '#{stop}'"
|
9
|
+
else
|
10
|
+
"BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
|
11
|
+
end
|
10
12
|
end
|
11
|
-
|
12
|
-
}
|
13
|
+
}
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
15
|
+
# Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
|
16
|
+
#
|
17
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
18
|
+
#
|
19
|
+
# range = (1..100) # => 1..100
|
20
|
+
#
|
21
|
+
# range.to_s # => "1..100"
|
22
|
+
# range.to_fs(:db) # => "BETWEEN '1' AND '100'"
|
23
|
+
#
|
24
|
+
# == Adding your own range formats to to_s
|
25
|
+
# You can add your own formats to the Range::RANGE_FORMATS hash.
|
26
|
+
# Use the format name as the hash key and a Proc instance.
|
27
|
+
#
|
28
|
+
# # config/initializers/range_formats.rb
|
29
|
+
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
|
30
|
+
def to_fs(format = :default)
|
31
|
+
if formatter = RANGE_FORMATS[format]
|
32
|
+
formatter.call(first, last)
|
33
|
+
else
|
34
|
+
to_s
|
35
|
+
end
|
32
36
|
end
|
37
|
+
alias_method :to_formatted_s, :to_fs
|
33
38
|
end
|
34
|
-
|
35
|
-
alias_method :to_default_s, :to_s
|
36
|
-
alias_method :to_formatted_s, :to_s
|
37
39
|
end
|
38
40
|
|
39
41
|
Range.prepend(ActiveSupport::RangeWithFormat)
|