activesupport 4.2.11.1 → 5.2.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +441 -399
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +91 -91
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +466 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +287 -196
- data/lib/active_support/callbacks.rb +640 -590
- data/lib/active_support/concern.rb +11 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/core_ext/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +101 -33
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +14 -9
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +99 -29
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +41 -14
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +69 -21
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +8 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +6 -5
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +62 -38
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +85 -51
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +152 -161
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +314 -38
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +131 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +5 -3
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +123 -28
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +37 -13
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +163 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +11 -58
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +8 -7
- data/lib/active_support/logger_silence.rb +6 -4
- data/lib/active_support/logger_thread_safe_level.rb +7 -5
- data/lib/active_support/message_encryptor.rb +168 -53
- data/lib/active_support/message_verifier.rb +150 -17
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +36 -23
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +11 -9
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -5
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +21 -16
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +19 -47
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +81 -15
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +169 -39
- data/lib/active_support/values/time_zone.rb +196 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -114
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +37 -37
- data/lib/active_support.rb +12 -11
- metadata +57 -27
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,4 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/regexp"
|
4
|
+
require "concurrent/map"
|
2
5
|
|
3
6
|
class Object
|
4
7
|
# An object is blank if it's false, empty, or a whitespace string.
|
@@ -100,6 +103,9 @@ end
|
|
100
103
|
|
101
104
|
class String
|
102
105
|
BLANK_RE = /\A[[:space:]]*\z/
|
106
|
+
ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
|
107
|
+
h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
|
108
|
+
end
|
103
109
|
|
104
110
|
# A string is blank if it's empty or contains whitespaces only:
|
105
111
|
#
|
@@ -114,7 +120,15 @@ class String
|
|
114
120
|
#
|
115
121
|
# @return [true, false]
|
116
122
|
def blank?
|
117
|
-
|
123
|
+
# The regexp that matches blank strings is expensive. For the case of empty
|
124
|
+
# strings we can speed up this method (~3.5x) with an empty? call. The
|
125
|
+
# penalty for the rest of strings is marginal.
|
126
|
+
empty? ||
|
127
|
+
begin
|
128
|
+
BLANK_RE.match?(self)
|
129
|
+
rescue Encoding::CompatibilityError
|
130
|
+
ENCODED_BLANKS[self.encoding].match?(self)
|
131
|
+
end
|
118
132
|
end
|
119
133
|
end
|
120
134
|
|
@@ -129,3 +143,14 @@ class Numeric #:nodoc:
|
|
129
143
|
false
|
130
144
|
end
|
131
145
|
end
|
146
|
+
|
147
|
+
class Time #:nodoc:
|
148
|
+
# No Time is blank:
|
149
|
+
#
|
150
|
+
# Time.now.blank? # => false
|
151
|
+
#
|
152
|
+
# @return [false]
|
153
|
+
def blank?
|
154
|
+
false
|
155
|
+
end
|
156
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/to_param"
|
4
|
+
require "active_support/core_ext/object/to_query"
|
5
|
+
require "active_support/core_ext/array/conversions"
|
6
|
+
require "active_support/core_ext/hash/conversions"
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
2
4
|
|
3
5
|
class Object
|
4
6
|
# Returns a deep copy of object if it's duplicable. If it's
|
@@ -25,7 +27,7 @@ class Array
|
|
25
27
|
# array[1][2] # => nil
|
26
28
|
# dup[1][2] # => 4
|
27
29
|
def deep_dup
|
28
|
-
map
|
30
|
+
map(&:deep_dup)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -39,8 +41,15 @@ class Hash
|
|
39
41
|
# hash[:a][:c] # => nil
|
40
42
|
# dup[:a][:c] # => "c"
|
41
43
|
def deep_dup
|
42
|
-
|
43
|
-
|
44
|
+
hash = dup
|
45
|
+
each_pair do |key, value|
|
46
|
+
if key.frozen? && ::String === key
|
47
|
+
hash[key] = value.deep_dup
|
48
|
+
else
|
49
|
+
hash.delete(key)
|
50
|
+
hash[key.deep_dup] = value.deep_dup
|
51
|
+
end
|
44
52
|
end
|
53
|
+
hash
|
45
54
|
end
|
46
55
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Most objects are cloneable, but not all. For example you can't dup methods:
|
3
5
|
#
|
@@ -19,7 +21,7 @@
|
|
19
21
|
class Object
|
20
22
|
# Can you safely dup this object?
|
21
23
|
#
|
22
|
-
# False for
|
24
|
+
# False for method objects;
|
23
25
|
# true otherwise.
|
24
26
|
def duplicable?
|
25
27
|
true
|
@@ -74,7 +76,7 @@ end
|
|
74
76
|
class Symbol
|
75
77
|
begin
|
76
78
|
:symbol.dup # Ruby 2.4.x.
|
77
|
-
|
79
|
+
"symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
|
78
80
|
rescue TypeError
|
79
81
|
|
80
82
|
# Symbols are not duplicable:
|
@@ -102,19 +104,14 @@ class Numeric
|
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
105
|
-
require
|
107
|
+
require "bigdecimal"
|
106
108
|
class BigDecimal
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
def duplicable?
|
114
|
-
true
|
115
|
-
end
|
116
|
-
rescue TypeError
|
117
|
-
# can't dup, so use superclass implementation
|
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
|
118
115
|
end
|
119
116
|
end
|
120
117
|
|
@@ -127,3 +124,33 @@ class Method
|
|
127
124
|
false
|
128
125
|
end
|
129
126
|
end
|
127
|
+
|
128
|
+
class Complex
|
129
|
+
begin
|
130
|
+
Complex(1).dup
|
131
|
+
rescue TypeError
|
132
|
+
|
133
|
+
# Complexes are not duplicable:
|
134
|
+
#
|
135
|
+
# Complex(1).duplicable? # => false
|
136
|
+
# Complex(1).dup # => TypeError: can't copy Complex
|
137
|
+
def duplicable?
|
138
|
+
false
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Rational
|
144
|
+
begin
|
145
|
+
Rational(1).dup
|
146
|
+
rescue TypeError
|
147
|
+
|
148
|
+
# Rationals are not duplicable:
|
149
|
+
#
|
150
|
+
# Rational(1).duplicable? # => false
|
151
|
+
# Rational(1).dup # => TypeError: can't copy Rational
|
152
|
+
def duplicable?
|
153
|
+
false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Object
|
2
4
|
# Returns true if this object is included in the argument. Argument must be
|
3
5
|
# any object which responds to +#include?+. Usage:
|
@@ -5,7 +7,7 @@ class Object
|
|
5
7
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
6
8
|
# "Konata".in?(characters) # => true
|
7
9
|
#
|
8
|
-
# This will throw an ArgumentError if the argument doesn't respond
|
10
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond
|
9
11
|
# to +#include?+.
|
10
12
|
def in?(another_object)
|
11
13
|
another_object.include?(self)
|
@@ -18,10 +20,10 @@ class Object
|
|
18
20
|
#
|
19
21
|
# params[:bucket_type].presence_in %w( project calendar )
|
20
22
|
#
|
21
|
-
# This will throw an ArgumentError if the argument doesn't respond to +#include?+.
|
23
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
|
22
24
|
#
|
23
25
|
# @return [Object]
|
24
26
|
def presence_in(another_object)
|
25
|
-
|
27
|
+
in?(another_object) ? self : nil
|
26
28
|
end
|
27
29
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Object
|
2
4
|
# Returns a hash with string keys that maps instance variable names without "@" to their
|
3
5
|
# corresponding values.
|
@@ -23,6 +25,6 @@ class Object
|
|
23
25
|
#
|
24
26
|
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
25
27
|
def instance_variable_names
|
26
|
-
instance_variables.map
|
28
|
+
instance_variables.map(&:to_s)
|
27
29
|
end
|
28
30
|
end
|
@@ -1,15 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Hack to load json gem first so we can overwrite its to_json.
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
4
|
+
require "json"
|
5
|
+
require "bigdecimal"
|
6
|
+
require "uri/generic"
|
7
|
+
require "pathname"
|
8
|
+
require "active_support/core_ext/big_decimal/conversions" # for #to_s
|
9
|
+
require "active_support/core_ext/hash/except"
|
10
|
+
require "active_support/core_ext/hash/slice"
|
11
|
+
require "active_support/core_ext/object/instance_variables"
|
12
|
+
require "time"
|
13
|
+
require "active_support/core_ext/time/conversions"
|
14
|
+
require "active_support/core_ext/date_time/conversions"
|
15
|
+
require "active_support/core_ext/date/conversions"
|
13
16
|
|
14
17
|
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
15
18
|
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
@@ -26,22 +29,25 @@ require 'active_support/core_ext/module/aliasing'
|
|
26
29
|
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
27
30
|
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
28
31
|
# should give exactly the same results with or without active support.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
|
33
|
+
module ActiveSupport
|
34
|
+
module ToJsonWithActiveSupportEncoder # :nodoc:
|
35
|
+
def to_json(options = nil)
|
32
36
|
if options.is_a?(::JSON::State)
|
33
37
|
# Called from JSON.{generate,dump}, forward it to JSON gem's to_json
|
34
|
-
|
38
|
+
super(options)
|
35
39
|
else
|
36
40
|
# to_json is being invoked directly, use ActiveSupport's encoder
|
37
41
|
ActiveSupport::JSON.encode(self, options)
|
38
42
|
end
|
39
43
|
end
|
40
|
-
|
41
|
-
alias_method_chain :to_json, :active_support_encoder
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
47
|
+
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
|
48
|
+
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
49
|
+
end
|
50
|
+
|
45
51
|
class Object
|
46
52
|
def as_json(options = nil) #:nodoc:
|
47
53
|
if respond_to?(:to_hash)
|
@@ -129,6 +135,12 @@ module Enumerable
|
|
129
135
|
end
|
130
136
|
end
|
131
137
|
|
138
|
+
class IO
|
139
|
+
def as_json(options = nil) #:nodoc:
|
140
|
+
to_s
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
132
144
|
class Range
|
133
145
|
def as_json(options = nil) #:nodoc:
|
134
146
|
to_s
|
@@ -185,13 +197,31 @@ class DateTime
|
|
185
197
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
186
198
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
187
199
|
else
|
188
|
-
strftime(
|
200
|
+
strftime("%Y/%m/%d %H:%M:%S %z")
|
189
201
|
end
|
190
202
|
end
|
191
203
|
end
|
192
204
|
|
205
|
+
class URI::Generic #:nodoc:
|
206
|
+
def as_json(options = nil)
|
207
|
+
to_s
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
class Pathname #:nodoc:
|
212
|
+
def as_json(options = nil)
|
213
|
+
to_s
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
193
217
|
class Process::Status #:nodoc:
|
194
218
|
def as_json(options = nil)
|
195
|
-
{ :
|
219
|
+
{ exitstatus: exitstatus, pid: pid }
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
class Exception
|
224
|
+
def as_json(options = nil)
|
225
|
+
to_s
|
196
226
|
end
|
197
227
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
2
4
|
|
3
5
|
class Object
|
4
6
|
# Alias of <tt>to_s</tt>.
|
@@ -38,7 +40,7 @@ class Array
|
|
38
40
|
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
39
41
|
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
40
42
|
def to_param
|
41
|
-
collect
|
43
|
+
collect(&:to_param).join "/"
|
42
44
|
end
|
43
45
|
|
44
46
|
# Converts an array into a string suitable for use as a URL query string,
|
@@ -51,7 +53,7 @@ class Array
|
|
51
53
|
if empty?
|
52
54
|
nil.to_query(prefix)
|
53
55
|
else
|
54
|
-
collect { |value| value.to_query(prefix) }.join
|
56
|
+
collect { |value| value.to_query(prefix) }.join "&"
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
@@ -73,11 +75,14 @@ class Hash
|
|
73
75
|
#
|
74
76
|
# This method is also aliased as +to_param+.
|
75
77
|
def to_query(namespace = nil)
|
76
|
-
collect do |key, value|
|
78
|
+
query = collect do |key, value|
|
77
79
|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
78
80
|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
79
81
|
end
|
80
|
-
end.compact
|
82
|
+
end.compact
|
83
|
+
|
84
|
+
query.sort! unless namespace.to_s.include?("[]")
|
85
|
+
query.join("&")
|
81
86
|
end
|
82
87
|
|
83
88
|
alias_method :to_param, :to_query
|
@@ -1,4 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module Tryable #:nodoc:
|
7
|
+
def try(*a, &b)
|
8
|
+
try!(*a, &b) if a.empty? || respond_to?(a.first)
|
9
|
+
end
|
10
|
+
|
11
|
+
def try!(*a, &b)
|
12
|
+
if a.empty? && block_given?
|
13
|
+
if b.arity == 0
|
14
|
+
instance_eval(&b)
|
15
|
+
else
|
16
|
+
yield self
|
17
|
+
end
|
18
|
+
else
|
19
|
+
public_send(*a, &b)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
1
25
|
class Object
|
26
|
+
include ActiveSupport::Tryable
|
27
|
+
|
28
|
+
##
|
29
|
+
# :method: try
|
30
|
+
#
|
31
|
+
# :call-seq:
|
32
|
+
# try(*a, &b)
|
33
|
+
#
|
2
34
|
# Invokes the public method whose name goes as first argument just like
|
3
35
|
# +public_send+ does, except that if the receiver does not respond to it the
|
4
36
|
# call returns +nil+ rather than raising an exception.
|
@@ -21,11 +53,11 @@ class Object
|
|
21
53
|
#
|
22
54
|
# +try+ will also return +nil+ if the receiver does not respond to the method:
|
23
55
|
#
|
24
|
-
# @person.try(:non_existing_method)
|
56
|
+
# @person.try(:non_existing_method) # => nil
|
25
57
|
#
|
26
58
|
# instead of
|
27
59
|
#
|
28
|
-
# @person.non_existing_method if @person.respond_to?(:non_existing_method)
|
60
|
+
# @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
|
29
61
|
#
|
30
62
|
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
|
31
63
|
# to the method:
|
@@ -56,27 +88,40 @@ class Object
|
|
56
88
|
#
|
57
89
|
# Please also note that +try+ is defined on +Object+. Therefore, it won't work
|
58
90
|
# with instances of classes that do not have +Object+ among their ancestors,
|
59
|
-
# like direct subclasses of +BasicObject+.
|
60
|
-
# +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
|
61
|
-
# the delegator itself.
|
62
|
-
def try(*a, &b)
|
63
|
-
try!(*a, &b) if a.empty? || respond_to?(a.first)
|
64
|
-
end
|
91
|
+
# like direct subclasses of +BasicObject+.
|
65
92
|
|
66
|
-
|
67
|
-
#
|
93
|
+
##
|
94
|
+
# :method: try!
|
95
|
+
#
|
96
|
+
# :call-seq:
|
97
|
+
# try!(*a, &b)
|
98
|
+
#
|
99
|
+
# Same as #try, but raises a +NoMethodError+ exception if the receiver is
|
100
|
+
# not +nil+ and does not implement the tried method.
|
101
|
+
#
|
102
|
+
# "a".try!(:upcase) # => "A"
|
103
|
+
# nil.try!(:upcase) # => nil
|
104
|
+
# 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
|
105
|
+
end
|
68
106
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
107
|
+
class Delegator
|
108
|
+
include ActiveSupport::Tryable
|
109
|
+
|
110
|
+
##
|
111
|
+
# :method: try
|
112
|
+
#
|
113
|
+
# :call-seq:
|
114
|
+
# try(a*, &b)
|
115
|
+
#
|
116
|
+
# See Object#try
|
117
|
+
|
118
|
+
##
|
119
|
+
# :method: try!
|
120
|
+
#
|
121
|
+
# :call-seq:
|
122
|
+
# try!(a*, &b)
|
123
|
+
#
|
124
|
+
# See Object#try!
|
80
125
|
end
|
81
126
|
|
82
127
|
class NilClass
|
@@ -94,6 +139,9 @@ class NilClass
|
|
94
139
|
nil
|
95
140
|
end
|
96
141
|
|
142
|
+
# Calling +try!+ on +nil+ always returns +nil+.
|
143
|
+
#
|
144
|
+
# nil.try!(:name) # => nil
|
97
145
|
def try!(*args)
|
98
146
|
nil
|
99
147
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/option_merger"
|
2
4
|
|
3
5
|
class Object
|
4
6
|
# An elegant way to factor duplication out of options passed to a series of
|
@@ -7,7 +9,7 @@ class Object
|
|
7
9
|
# provided. Each method called on the block variable must take an options
|
8
10
|
# hash as its final argument.
|
9
11
|
#
|
10
|
-
# Without <tt>with_options
|
12
|
+
# Without <tt>with_options</tt>, this code contains duplication:
|
11
13
|
#
|
12
14
|
# class Account < ActiveRecord::Base
|
13
15
|
# has_many :customers, dependent: :destroy
|
@@ -60,7 +62,18 @@ class Object
|
|
60
62
|
#
|
61
63
|
# validates :content, length: { minimum: 50 }, if: -> { content.present? }
|
62
64
|
#
|
63
|
-
# Hence the inherited default for
|
65
|
+
# Hence the inherited default for +if+ key is ignored.
|
66
|
+
#
|
67
|
+
# NOTE: You cannot call class methods implicitly inside of with_options.
|
68
|
+
# You can access these methods using the class name instead:
|
69
|
+
#
|
70
|
+
# class Phone < ActiveRecord::Base
|
71
|
+
# enum phone_number_type: [home: 0, office: 1, mobile: 2]
|
72
|
+
#
|
73
|
+
# with_options presence: true do
|
74
|
+
# validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
|
75
|
+
# end
|
76
|
+
# end
|
64
77
|
#
|
65
78
|
def with_options(options, &block)
|
66
79
|
option_merger = ActiveSupport::OptionMerger.new(self, options)
|
@@ -1,15 +1,16 @@
|
|
1
|
-
|
2
|
-
require 'active_support/core_ext/object/blank'
|
3
|
-
require 'active_support/core_ext/object/duplicable'
|
4
|
-
require 'active_support/core_ext/object/deep_dup'
|
5
|
-
require 'active_support/core_ext/object/itself'
|
6
|
-
require 'active_support/core_ext/object/try'
|
7
|
-
require 'active_support/core_ext/object/inclusion'
|
1
|
+
# frozen_string_literal: true
|
8
2
|
|
9
|
-
require
|
10
|
-
require
|
3
|
+
require "active_support/core_ext/object/acts_like"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/core_ext/object/duplicable"
|
6
|
+
require "active_support/core_ext/object/deep_dup"
|
7
|
+
require "active_support/core_ext/object/try"
|
8
|
+
require "active_support/core_ext/object/inclusion"
|
11
9
|
|
12
|
-
require
|
13
|
-
require
|
14
|
-
|
15
|
-
require
|
10
|
+
require "active_support/core_ext/object/conversions"
|
11
|
+
require "active_support/core_ext/object/instance_variables"
|
12
|
+
|
13
|
+
require "active_support/core_ext/object/json"
|
14
|
+
require "active_support/core_ext/object/to_param"
|
15
|
+
require "active_support/core_ext/object/to_query"
|
16
|
+
require "active_support/core_ext/object/with_options"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module CompareWithRange #:nodoc:
|
5
|
+
# Extends the default Range#=== to support range comparisons.
|
6
|
+
# (1..5) === (1..5) # => true
|
7
|
+
# (1..5) === (2..3) # => true
|
8
|
+
# (1..5) === (2..6) # => false
|
9
|
+
#
|
10
|
+
# The native Range#=== behavior is untouched.
|
11
|
+
# ('a'..'f') === ('c') # => true
|
12
|
+
# (5..9) === (11) # => false
|
13
|
+
def ===(value)
|
14
|
+
if value.is_a?(::Range)
|
15
|
+
# 1...10 includes 1..9 but it does not include 1..10.
|
16
|
+
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
17
|
+
super(value.first) && value.last.send(operator, last)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Extends the default Range#include? to support range comparisons.
|
24
|
+
# (1..5).include?(1..5) # => true
|
25
|
+
# (1..5).include?(2..3) # => true
|
26
|
+
# (1..5).include?(2..6) # => false
|
27
|
+
#
|
28
|
+
# The native Range#include? behavior is untouched.
|
29
|
+
# ('a'..'f').include?('c') # => true
|
30
|
+
# (5..9).include?(11) # => false
|
31
|
+
def include?(value)
|
32
|
+
if value.is_a?(::Range)
|
33
|
+
# 1...10 includes 1..9 but it does not include 1..10.
|
34
|
+
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
35
|
+
super(value.first) && value.last.send(operator, last)
|
36
|
+
else
|
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)
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Range.prepend(ActiveSupport::CompareWithRange)
|
@@ -1,19 +1,39 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport::RangeWithFormat
|
2
4
|
RANGE_FORMATS = {
|
3
|
-
:
|
5
|
+
db: -> (start, stop) do
|
6
|
+
case start
|
7
|
+
when String then "BETWEEN '#{start}' AND '#{stop}'"
|
8
|
+
else
|
9
|
+
"BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
|
10
|
+
end
|
11
|
+
end
|
4
12
|
}
|
5
13
|
|
6
|
-
#
|
14
|
+
# Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
|
15
|
+
#
|
16
|
+
# range = (1..100) # => 1..100
|
7
17
|
#
|
8
|
-
#
|
9
|
-
|
18
|
+
# range.to_s # => "1..100"
|
19
|
+
# range.to_s(:db) # => "BETWEEN '1' AND '100'"
|
20
|
+
#
|
21
|
+
# == Adding your own range formats to to_s
|
22
|
+
# You can add your own formats to the Range::RANGE_FORMATS hash.
|
23
|
+
# Use the format name as the hash key and a Proc instance.
|
24
|
+
#
|
25
|
+
# # config/initializers/range_formats.rb
|
26
|
+
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
|
27
|
+
def to_s(format = :default)
|
10
28
|
if formatter = RANGE_FORMATS[format]
|
11
29
|
formatter.call(first, last)
|
12
30
|
else
|
13
|
-
|
31
|
+
super()
|
14
32
|
end
|
15
33
|
end
|
16
34
|
|
17
35
|
alias_method :to_default_s, :to_s
|
18
|
-
alias_method :
|
36
|
+
alias_method :to_formatted_s, :to_s
|
19
37
|
end
|
38
|
+
|
39
|
+
Range.prepend(ActiveSupport::RangeWithFormat)
|