activesupport 4.0.12 → 7.0.2.4
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 +5 -5
- data/CHANGELOG.md +249 -501
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +41 -13
- data/lib/active_support/benchmarkable.rb +7 -15
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +96 -74
- data/lib/active_support/cache/mem_cache_store.rb +211 -103
- data/lib/active_support/cache/memory_store.rb +90 -58
- data/lib/active_support/cache/null_store.rb +19 -7
- data/lib/active_support/cache/redis_cache_store.rb +468 -0
- data/lib/active_support/cache/strategy/local_cache.rb +86 -83
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +580 -241
- data/lib/active_support/callbacks.rb +812 -425
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +103 -14
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +21 -19
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +47 -1
- data/lib/active_support/core_ext/array/conversions.rb +35 -44
- 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/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +26 -16
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +10 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +25 -26
- data/lib/active_support/core_ext/class.rb +4 -4
- 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 +31 -18
- data/lib/active_support/core_ext/date/conversions.rb +43 -32
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +7 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- 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 +79 -38
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +8 -4
- data/lib/active_support/core_ext/digest/uuid.rb +79 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +249 -17
- data/lib/active_support/core_ext/file/atomic.rb +41 -32
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +14 -5
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +39 -56
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -23
- data/lib/active_support/core_ext/hash.rb +10 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- 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 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +172 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +23 -38
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -10
- data/lib/active_support/core_ext/name_error.rb +45 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +70 -20
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +17 -47
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +244 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +106 -26
- data/lib/active_support/core_ext/object/with_options.rb +64 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- 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 +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -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 +10 -1
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +42 -51
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +18 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +97 -7
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +106 -25
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +18 -9
- data/lib/active_support/core_ext/string/output_safety.rb +227 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- 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/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +178 -116
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +37 -25
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +44 -42
- data/lib/active_support/core_ext/time.rb +8 -5
- data/lib/active_support/core_ext/uri.rb +4 -25
- data/lib/active_support/core_ext.rb +4 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +49 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +71 -696
- data/lib/active_support/deprecation/behaviors.rb +65 -16
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +62 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
- data/lib/active_support/deprecation/reporting.rb +81 -18
- data/lib/active_support/deprecation.rb +19 -11
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +67 -0
- data/lib/active_support/duration.rb +437 -39
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- 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 +170 -0
- 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 +151 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +207 -54
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +10 -6
- data/lib/active_support/i18n_railtie.rb +48 -19
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +97 -37
- data/lib/active_support/inflector/methods.rb +192 -157
- data/lib/active_support/inflector/transliterate.rb +83 -33
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +64 -0
- data/lib/active_support/json/decoding.rb +37 -42
- data/lib/active_support/json/encoding.rb +93 -293
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +30 -47
- data/lib/active_support/lazy_load_hooks.rb +54 -21
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +61 -18
- data/lib/active_support/logger.rb +40 -4
- data/lib/active_support/logger_silence.rb +17 -20
- data/lib/active_support/logger_thread_safe_level.rb +69 -0
- data/lib/active_support/message_encryptor.rb +178 -55
- data/lib/active_support/message_verifier.rb +195 -26
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +45 -92
- data/lib/active_support/multibyte/unicode.rb +44 -377
- data/lib/active_support/multibyte.rb +5 -3
- data/lib/active_support/notifications/fanout.rb +177 -44
- data/lib/active_support/notifications/instrumenter.rb +117 -17
- data/lib/active_support/notifications.rb +106 -39
- data/lib/active_support/number_helper/number_converter.rb +181 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +152 -394
- data/lib/active_support/option_merger.rb +18 -5
- data/lib/active_support/ordered_hash.rb +8 -6
- data/lib/active_support/ordered_options.rb +43 -7
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +24 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -11
- data/lib/active_support/railtie.rb +118 -12
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +112 -57
- 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 +38 -0
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +109 -39
- data/lib/active_support/tagged_logging.rb +54 -17
- data/lib/active_support/test_case.rb +121 -37
- data/lib/active_support/testing/assertions.rb +177 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +65 -11
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +56 -87
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- 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/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +6 -4
- data/lib/active_support/testing/time_helpers.rb +246 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +315 -90
- data/lib/active_support/values/time_zone.rb +306 -135
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +117 -115
- data/lib/active_support/xml_mini/libxml.rb +22 -21
- data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
- data/lib/active_support/xml_mini/nokogiri.rb +19 -19
- data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
- data/lib/active_support/xml_mini/rexml.rb +25 -17
- data/lib/active_support/xml_mini.rb +67 -56
- data/lib/active_support.rb +58 -3
- metadata +125 -66
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/marshal.rb +0 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,39 +1,47 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
2
4
|
|
3
5
|
class Object
|
4
6
|
# An object is blank if it's false, empty, or a whitespace string.
|
5
|
-
# For example, '', ' ',
|
7
|
+
# For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
|
8
|
+
#
|
9
|
+
# This simplifies
|
6
10
|
#
|
7
|
-
#
|
11
|
+
# !address || address.empty?
|
8
12
|
#
|
9
|
-
#
|
13
|
+
# to
|
10
14
|
#
|
11
|
-
#
|
15
|
+
# address.blank?
|
12
16
|
#
|
13
|
-
#
|
17
|
+
# @return [true, false]
|
14
18
|
def blank?
|
15
|
-
respond_to?(:empty?) ? empty? : !self
|
19
|
+
respond_to?(:empty?) ? !!empty? : !self
|
16
20
|
end
|
17
21
|
|
18
|
-
# An object is present if it's not
|
22
|
+
# An object is present if it's not blank.
|
23
|
+
#
|
24
|
+
# @return [true, false]
|
19
25
|
def present?
|
20
26
|
!blank?
|
21
27
|
end
|
22
28
|
|
23
|
-
# Returns
|
24
|
-
# <tt>object.presence</tt> is equivalent to
|
29
|
+
# Returns the receiver if it's present otherwise returns +nil+.
|
30
|
+
# <tt>object.presence</tt> is equivalent to
|
25
31
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
32
|
+
# object.present? ? object : nil
|
33
|
+
#
|
34
|
+
# For example, something like
|
29
35
|
#
|
30
36
|
# state = params[:state] if params[:state].present?
|
31
37
|
# country = params[:country] if params[:country].present?
|
32
38
|
# region = state || country || 'US'
|
33
39
|
#
|
34
|
-
#
|
40
|
+
# becomes
|
35
41
|
#
|
36
42
|
# region = params[:state].presence || params[:country].presence || 'US'
|
43
|
+
#
|
44
|
+
# @return [Object]
|
37
45
|
def presence
|
38
46
|
self if present?
|
39
47
|
end
|
@@ -43,6 +51,8 @@ class NilClass
|
|
43
51
|
# +nil+ is blank:
|
44
52
|
#
|
45
53
|
# nil.blank? # => true
|
54
|
+
#
|
55
|
+
# @return [true]
|
46
56
|
def blank?
|
47
57
|
true
|
48
58
|
end
|
@@ -52,6 +62,8 @@ class FalseClass
|
|
52
62
|
# +false+ is blank:
|
53
63
|
#
|
54
64
|
# false.blank? # => true
|
65
|
+
#
|
66
|
+
# @return [true]
|
55
67
|
def blank?
|
56
68
|
true
|
57
69
|
end
|
@@ -61,6 +73,8 @@ class TrueClass
|
|
61
73
|
# +true+ is not blank:
|
62
74
|
#
|
63
75
|
# true.blank? # => false
|
76
|
+
#
|
77
|
+
# @return [false]
|
64
78
|
def blank?
|
65
79
|
false
|
66
80
|
end
|
@@ -71,6 +85,8 @@ class Array
|
|
71
85
|
#
|
72
86
|
# [].blank? # => true
|
73
87
|
# [1,2,3].blank? # => false
|
88
|
+
#
|
89
|
+
# @return [true, false]
|
74
90
|
alias_method :blank?, :empty?
|
75
91
|
end
|
76
92
|
|
@@ -79,26 +95,60 @@ class Hash
|
|
79
95
|
#
|
80
96
|
# {}.blank? # => true
|
81
97
|
# { key: 'value' }.blank? # => false
|
98
|
+
#
|
99
|
+
# @return [true, false]
|
82
100
|
alias_method :blank?, :empty?
|
83
101
|
end
|
84
102
|
|
85
103
|
class String
|
104
|
+
BLANK_RE = /\A[[:space:]]*\z/
|
105
|
+
ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
|
106
|
+
h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
|
107
|
+
end
|
108
|
+
|
86
109
|
# A string is blank if it's empty or contains whitespaces only:
|
87
110
|
#
|
88
|
-
# ''.blank?
|
89
|
-
# ' '.blank?
|
90
|
-
#
|
91
|
-
# '
|
111
|
+
# ''.blank? # => true
|
112
|
+
# ' '.blank? # => true
|
113
|
+
# "\t\n\r".blank? # => true
|
114
|
+
# ' blah '.blank? # => false
|
115
|
+
#
|
116
|
+
# Unicode whitespace is supported:
|
117
|
+
#
|
118
|
+
# "\u00a0".blank? # => true
|
119
|
+
#
|
120
|
+
# @return [true, false]
|
92
121
|
def blank?
|
93
|
-
|
122
|
+
# The regexp that matches blank strings is expensive. For the case of empty
|
123
|
+
# strings we can speed up this method (~3.5x) with an empty? call. The
|
124
|
+
# penalty for the rest of strings is marginal.
|
125
|
+
empty? ||
|
126
|
+
begin
|
127
|
+
BLANK_RE.match?(self)
|
128
|
+
rescue Encoding::CompatibilityError
|
129
|
+
ENCODED_BLANKS[self.encoding].match?(self)
|
130
|
+
end
|
94
131
|
end
|
95
132
|
end
|
96
133
|
|
97
|
-
class Numeric
|
134
|
+
class Numeric # :nodoc:
|
98
135
|
# No number is blank:
|
99
136
|
#
|
100
137
|
# 1.blank? # => false
|
101
138
|
# 0.blank? # => false
|
139
|
+
#
|
140
|
+
# @return [false]
|
141
|
+
def blank?
|
142
|
+
false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class Time # :nodoc:
|
147
|
+
# No Time is blank:
|
148
|
+
#
|
149
|
+
# Time.now.blank? # => false
|
150
|
+
#
|
151
|
+
# @return [false]
|
102
152
|
def blank?
|
103
153
|
false
|
104
154
|
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
|
@@ -8,8 +10,8 @@ class Object
|
|
8
10
|
# dup = object.deep_dup
|
9
11
|
# dup.instance_variable_set(:@a, 1)
|
10
12
|
#
|
11
|
-
# object.instance_variable_defined?(:@a)
|
12
|
-
# dup.instance_variable_defined?(:@a)
|
13
|
+
# object.instance_variable_defined?(:@a) # => false
|
14
|
+
# dup.instance_variable_defined?(:@a) # => true
|
13
15
|
def deep_dup
|
14
16
|
duplicable? ? dup : self
|
15
17
|
end
|
@@ -22,10 +24,10 @@ class Array
|
|
22
24
|
# dup = array.deep_dup
|
23
25
|
# dup[1][2] = 4
|
24
26
|
#
|
25
|
-
# array[1][2]
|
26
|
-
# dup[1][2]
|
27
|
+
# array[1][2] # => nil
|
28
|
+
# dup[1][2] # => 4
|
27
29
|
def deep_dup
|
28
|
-
map
|
30
|
+
map(&:deep_dup)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -36,11 +38,18 @@ class Hash
|
|
36
38
|
# dup = hash.deep_dup
|
37
39
|
# dup[:a][:c] = 'c'
|
38
40
|
#
|
39
|
-
# hash[:a][:c]
|
40
|
-
# dup[:a][:c]
|
41
|
+
# hash[:a][:c] # => nil
|
42
|
+
# dup[:a][:c] # => "c"
|
41
43
|
def deep_dup
|
42
|
-
|
43
|
-
|
44
|
+
hash = dup
|
45
|
+
each_pair do |key, value|
|
46
|
+
if ::String === key || ::Symbol === 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,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
|
-
# Most objects are cloneable, but not all. For example you can't dup
|
4
|
+
# Most objects are cloneable, but not all. For example you can't dup methods:
|
3
5
|
#
|
4
|
-
#
|
6
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
5
7
|
#
|
6
8
|
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
7
9
|
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
@@ -19,72 +21,40 @@
|
|
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
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
class
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# nil.duplicable? # => false
|
33
|
-
# nil.dup # => TypeError: can't dup NilClass
|
34
|
-
def duplicable?
|
35
|
-
false
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class FalseClass
|
40
|
-
# +false+ is not duplicable:
|
31
|
+
class Method
|
32
|
+
# Methods are not duplicable:
|
41
33
|
#
|
42
|
-
#
|
43
|
-
#
|
34
|
+
# method(:puts).duplicable? # => false
|
35
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
44
36
|
def duplicable?
|
45
37
|
false
|
46
38
|
end
|
47
39
|
end
|
48
40
|
|
49
|
-
class
|
50
|
-
#
|
41
|
+
class UnboundMethod
|
42
|
+
# Unbound methods are not duplicable:
|
51
43
|
#
|
52
|
-
#
|
53
|
-
#
|
44
|
+
# method(:puts).unbind.duplicable? # => false
|
45
|
+
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
54
46
|
def duplicable?
|
55
47
|
false
|
56
48
|
end
|
57
49
|
end
|
58
50
|
|
59
|
-
|
60
|
-
# Symbols are not duplicable:
|
61
|
-
#
|
62
|
-
# :my_symbol.duplicable? # => false
|
63
|
-
# :my_symbol.dup # => TypeError: can't dup Symbol
|
64
|
-
def duplicable?
|
65
|
-
false
|
66
|
-
end
|
67
|
-
end
|
51
|
+
require "singleton"
|
68
52
|
|
69
|
-
|
70
|
-
#
|
53
|
+
module Singleton
|
54
|
+
# Singleton instances are not duplicable:
|
71
55
|
#
|
72
|
-
#
|
73
|
-
# 3.dup # => TypeError: can't dup Fixnum
|
56
|
+
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
74
57
|
def duplicable?
|
75
58
|
false
|
76
59
|
end
|
77
60
|
end
|
78
|
-
|
79
|
-
require 'bigdecimal'
|
80
|
-
class BigDecimal
|
81
|
-
begin
|
82
|
-
BigDecimal.new('4.56').dup
|
83
|
-
|
84
|
-
def duplicable?
|
85
|
-
true
|
86
|
-
end
|
87
|
-
rescue TypeError
|
88
|
-
# can't dup, so use superclass implementation
|
89
|
-
end
|
90
|
-
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Object
|
4
4
|
# Returns true if this object is included in the argument. Argument must be
|
@@ -7,20 +7,23 @@ class Object
|
|
7
7
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
8
8
|
# "Konata".in?(characters) # => true
|
9
9
|
#
|
10
|
-
# This will throw an ArgumentError if the argument doesn't respond
|
10
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond
|
11
11
|
# to +#include?+.
|
12
|
-
def in?(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
def in?(another_object)
|
13
|
+
another_object.include?(self)
|
14
|
+
rescue NoMethodError
|
15
|
+
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the receiver if it's included in the argument otherwise returns +nil+.
|
19
|
+
# Argument must be any object which responds to +#include?+. Usage:
|
20
|
+
#
|
21
|
+
# params[:bucket_type].presence_in %w( project calendar )
|
22
|
+
#
|
23
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
|
24
|
+
#
|
25
|
+
# @return [Object]
|
26
|
+
def presence_in(another_object)
|
27
|
+
in?(another_object) ? self : nil
|
25
28
|
end
|
26
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
|
@@ -0,0 +1,244 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Hack to load json gem first so we can overwrite its to_json.
|
4
|
+
require "json"
|
5
|
+
require "bigdecimal"
|
6
|
+
require "ipaddr"
|
7
|
+
require "uri/generic"
|
8
|
+
require "pathname"
|
9
|
+
require "active_support/core_ext/big_decimal/conversions" # for #to_s
|
10
|
+
require "active_support/core_ext/hash/except"
|
11
|
+
require "active_support/core_ext/hash/slice"
|
12
|
+
require "active_support/core_ext/object/instance_variables"
|
13
|
+
require "time"
|
14
|
+
require "active_support/core_ext/time/conversions"
|
15
|
+
require "active_support/core_ext/date_time/conversions"
|
16
|
+
require "active_support/core_ext/date/conversions"
|
17
|
+
|
18
|
+
#--
|
19
|
+
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
20
|
+
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
21
|
+
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
22
|
+
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance.
|
23
|
+
#
|
24
|
+
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
25
|
+
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
26
|
+
# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
|
27
|
+
# calls to the original to_json method.
|
28
|
+
#
|
29
|
+
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
|
30
|
+
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
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 active support.
|
33
|
+
|
34
|
+
module ActiveSupport
|
35
|
+
module ToJsonWithActiveSupportEncoder # :nodoc:
|
36
|
+
def to_json(options = nil)
|
37
|
+
if options.is_a?(::JSON::State)
|
38
|
+
# Called from JSON.{generate,dump}, forward it to JSON gem's to_json
|
39
|
+
super(options)
|
40
|
+
else
|
41
|
+
# to_json is being invoked directly, use ActiveSupport's encoder
|
42
|
+
ActiveSupport::JSON.encode(self, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
|
49
|
+
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
50
|
+
end
|
51
|
+
|
52
|
+
class Module
|
53
|
+
def as_json(options = nil) # :nodoc:
|
54
|
+
name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Object
|
59
|
+
def as_json(options = nil) # :nodoc:
|
60
|
+
if respond_to?(:to_hash)
|
61
|
+
to_hash.as_json(options)
|
62
|
+
else
|
63
|
+
instance_values.as_json(options)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Struct # :nodoc:
|
69
|
+
def as_json(options = nil)
|
70
|
+
Hash[members.zip(values)].as_json(options)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class TrueClass
|
75
|
+
def as_json(options = nil) # :nodoc:
|
76
|
+
self
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class FalseClass
|
81
|
+
def as_json(options = nil) # :nodoc:
|
82
|
+
self
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class NilClass
|
87
|
+
def as_json(options = nil) # :nodoc:
|
88
|
+
self
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class String
|
93
|
+
def as_json(options = nil) # :nodoc:
|
94
|
+
self
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class Symbol
|
99
|
+
def as_json(options = nil) # :nodoc:
|
100
|
+
to_s
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Numeric
|
105
|
+
def as_json(options = nil) # :nodoc:
|
106
|
+
self
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Float
|
111
|
+
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
112
|
+
# "Infinity" or "NaN" which are not valid JSON.
|
113
|
+
def as_json(options = nil) # :nodoc:
|
114
|
+
finite? ? self : nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class BigDecimal
|
119
|
+
# A BigDecimal would be naturally represented as a JSON number. Most libraries,
|
120
|
+
# however, parse non-integer JSON numbers directly as floats. Clients using
|
121
|
+
# those libraries would get in general a wrong number and no way to recover
|
122
|
+
# other than manually inspecting the string with the JSON code itself.
|
123
|
+
#
|
124
|
+
# That's why a JSON string is returned. The JSON literal is not numeric, but
|
125
|
+
# if the other end knows by contract that the data is supposed to be a
|
126
|
+
# BigDecimal, it still has the chance to post-process the string and get the
|
127
|
+
# real value.
|
128
|
+
def as_json(options = nil) # :nodoc:
|
129
|
+
finite? ? to_s : nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Regexp
|
134
|
+
def as_json(options = nil) # :nodoc:
|
135
|
+
to_s
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
module Enumerable
|
140
|
+
def as_json(options = nil) # :nodoc:
|
141
|
+
to_a.as_json(options)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class IO
|
146
|
+
def as_json(options = nil) # :nodoc:
|
147
|
+
to_s
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class Range
|
152
|
+
def as_json(options = nil) # :nodoc:
|
153
|
+
to_s
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Array
|
158
|
+
def as_json(options = nil) # :nodoc:
|
159
|
+
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class Hash
|
164
|
+
def as_json(options = nil) # :nodoc:
|
165
|
+
# create a subset of the hash by applying :only or :except
|
166
|
+
subset = if options
|
167
|
+
if attrs = options[:only]
|
168
|
+
slice(*Array(attrs))
|
169
|
+
elsif attrs = options[:except]
|
170
|
+
except(*Array(attrs))
|
171
|
+
else
|
172
|
+
self
|
173
|
+
end
|
174
|
+
else
|
175
|
+
self
|
176
|
+
end
|
177
|
+
|
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
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class Time
|
187
|
+
def as_json(options = nil) # :nodoc:
|
188
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
189
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
190
|
+
else
|
191
|
+
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class Date
|
197
|
+
def as_json(options = nil) # :nodoc:
|
198
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
199
|
+
strftime("%Y-%m-%d")
|
200
|
+
else
|
201
|
+
strftime("%Y/%m/%d")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
class DateTime
|
207
|
+
def as_json(options = nil) # :nodoc:
|
208
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
209
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
210
|
+
else
|
211
|
+
strftime("%Y/%m/%d %H:%M:%S %z")
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
class URI::Generic # :nodoc:
|
217
|
+
def as_json(options = nil)
|
218
|
+
to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class Pathname # :nodoc:
|
223
|
+
def as_json(options = nil)
|
224
|
+
to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class IPAddr # :nodoc:
|
229
|
+
def as_json(options = nil)
|
230
|
+
to_s
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class Process::Status # :nodoc:
|
235
|
+
def as_json(options = nil)
|
236
|
+
{ exitstatus: exitstatus, pid: pid }
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class Exception
|
241
|
+
def as_json(options = nil)
|
242
|
+
to_s
|
243
|
+
end
|
244
|
+
end
|