activesupport 6.1.0 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1075 -325
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +4 -2
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +32 -7
- data/lib/active_support/benchmarkable.rb +3 -2
- data/lib/active_support/broadcast_logger.rb +251 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +53 -20
- data/lib/active_support/cache/mem_cache_store.rb +201 -62
- data/lib/active_support/cache/memory_store.rb +86 -24
- data/lib/active_support/cache/null_store.rb +16 -2
- data/lib/active_support/cache/redis_cache_store.rb +186 -193
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +63 -71
- data/lib/active_support/cache.rb +487 -249
- data/lib/active_support/callbacks.rb +227 -105
- data/lib/active_support/code_generator.rb +70 -0
- data/lib/active_support/concern.rb +9 -7
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +18 -5
- data/lib/active_support/configuration_file.rb +7 -2
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +15 -13
- 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/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +37 -26
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +16 -15
- data/lib/active_support/core_ext/date_and_time/calculations.rb +14 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
- data/lib/active_support/core_ext/digest/uuid.rb +30 -13
- data/lib/active_support/core_ext/enumerable.rb +85 -83
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +1 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- 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/module/attribute_accessors.rb +8 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +49 -22
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +81 -43
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +82 -77
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
- data/lib/active_support/core_ext/object/duplicable.rb +31 -11
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +49 -27
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +25 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +34 -13
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +25 -13
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +17 -10
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +85 -165
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +30 -8
- data/lib/active_support/core_ext/time/conversions.rb +15 -13
- data/lib/active_support/core_ext/time/zones.rb +12 -28
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes.rb +47 -20
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +66 -40
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/instance_delegator.rb +31 -4
- data/lib/active_support/deprecation/method_wrappers.rb +9 -26
- data/lib/active_support/deprecation/proxy_wrappers.rb +38 -23
- data/lib/active_support/deprecation/reporting.rb +43 -26
- data/lib/active_support/deprecation.rb +32 -5
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +150 -72
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -3
- data/lib/active_support/duration.rb +83 -52
- data/lib/active_support/encrypted_configuration.rb +72 -9
- data/lib/active_support/encrypted_file.rb +29 -13
- data/lib/active_support/environment_inquirer.rb +23 -3
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +203 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- 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 -22
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +28 -11
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +44 -19
- data/lib/active_support/html_safe_translation.rb +53 -0
- data/lib/active_support/i18n.rb +2 -1
- data/lib/active_support/i18n_railtie.rb +21 -14
- data/lib/active_support/inflector/inflections.rb +25 -7
- data/lib/active_support/inflector/methods.rb +50 -64
- data/lib/active_support/inflector/transliterate.rb +4 -2
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +2 -1
- data/lib/active_support/json/encoding.rb +27 -45
- data/lib/active_support/key_generator.rb +31 -6
- data/lib/active_support/lazy_load_hooks.rb +33 -7
- data/lib/active_support/locale/en.yml +4 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +97 -35
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_thread_safe_level.rb +11 -34
- data/lib/active_support/message_encryptor.rb +206 -56
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +235 -84
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +112 -46
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +12 -11
- data/lib/active_support/multibyte/unicode.rb +9 -49
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +304 -114
- data/lib/active_support/notifications/instrumenter.rb +117 -35
- data/lib/active_support/notifications.rb +25 -25
- data/lib/active_support/number_helper/number_converter.rb +14 -7
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -4
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
- data/lib/active_support/number_helper/rounding_helper.rb +2 -6
- data/lib/active_support/number_helper.rb +379 -319
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +4 -4
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/parameter_filter.rb +105 -81
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/railtie.rb +83 -21
- data/lib/active_support/reloader.rb +13 -5
- data/lib/active_support/rescuable.rb +18 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +18 -11
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +3 -3
- data/lib/active_support/subscriber.rb +11 -40
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +65 -25
- data/lib/active_support/test_case.rb +166 -27
- data/lib/active_support/testing/assertions.rb +61 -15
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +53 -2
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +24 -11
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +4 -6
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +49 -16
- data/lib/active_support/time_with_zone.rb +39 -28
- data/lib/active_support/values/time_zone.rb +50 -18
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +4 -11
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -5
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- data/lib/active_support/xml_mini.rb +7 -6
- data/lib/active_support.rb +28 -1
- metadata +150 -18
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -28
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/uri.rb +0 -29
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
- data/lib/active_support/per_thread_registry.rb +0 -60
@@ -5,9 +5,13 @@ require "active_support/number_helper"
|
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
7
|
module NumericWithFormat
|
8
|
+
# \Numeric With Format
|
9
|
+
#
|
8
10
|
# Provides options for converting numbers into formatted strings.
|
9
11
|
# Options are provided for phone numbers, currency, percentage,
|
10
|
-
# precision, positional notation, file size and pretty printing.
|
12
|
+
# precision, positional notation, file size, and pretty printing.
|
13
|
+
#
|
14
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
11
15
|
#
|
12
16
|
# ==== Options
|
13
17
|
#
|
@@ -16,102 +20,102 @@ module ActiveSupport
|
|
16
20
|
# ==== Examples
|
17
21
|
#
|
18
22
|
# Phone Numbers:
|
19
|
-
# 5551234.
|
20
|
-
# 1235551234.
|
21
|
-
# 1235551234.
|
22
|
-
# 1235551234.
|
23
|
-
# 1235551234.
|
24
|
-
# 1235551234.
|
25
|
-
# 1235551234.
|
23
|
+
# 5551234.to_fs(:phone) # => "555-1234"
|
24
|
+
# 1235551234.to_fs(:phone) # => "123-555-1234"
|
25
|
+
# 1235551234.to_fs(:phone, area_code: true) # => "(123) 555-1234"
|
26
|
+
# 1235551234.to_fs(:phone, delimiter: ' ') # => "123 555 1234"
|
27
|
+
# 1235551234.to_fs(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
|
28
|
+
# 1235551234.to_fs(:phone, country_code: 1) # => "+1-123-555-1234"
|
29
|
+
# 1235551234.to_fs(:phone, country_code: 1, extension: 1343, delimiter: '.')
|
26
30
|
# # => "+1.123.555.1234 x 1343"
|
27
31
|
#
|
28
32
|
# Currency:
|
29
|
-
# 1234567890.50.
|
30
|
-
# 1234567890.506.
|
31
|
-
# 1234567890.506.
|
32
|
-
# 1234567890.506.
|
33
|
-
# 1234567890.506.
|
34
|
-
# -1234567890.50.
|
33
|
+
# 1234567890.50.to_fs(:currency) # => "$1,234,567,890.50"
|
34
|
+
# 1234567890.506.to_fs(:currency) # => "$1,234,567,890.51"
|
35
|
+
# 1234567890.506.to_fs(:currency, precision: 3) # => "$1,234,567,890.506"
|
36
|
+
# 1234567890.506.to_fs(:currency, round_mode: :down) # => "$1,234,567,890.50"
|
37
|
+
# 1234567890.506.to_fs(:currency, locale: :fr) # => "1 234 567 890,51 €"
|
38
|
+
# -1234567890.50.to_fs(:currency, negative_format: '(%u%n)')
|
35
39
|
# # => "($1,234,567,890.50)"
|
36
|
-
# 1234567890.50.
|
40
|
+
# 1234567890.50.to_fs(:currency, unit: '£', separator: ',', delimiter: '')
|
37
41
|
# # => "£1234567890,50"
|
38
|
-
# 1234567890.50.
|
42
|
+
# 1234567890.50.to_fs(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
|
39
43
|
# # => "1234567890,50 £"
|
40
44
|
#
|
41
45
|
# Percentage:
|
42
|
-
# 100.
|
43
|
-
# 100.
|
44
|
-
# 1000.
|
45
|
-
# 302.24398923423.
|
46
|
-
# 302.24398923423.
|
47
|
-
# 1000.
|
48
|
-
# 100.
|
46
|
+
# 100.to_fs(:percentage) # => "100.000%"
|
47
|
+
# 100.to_fs(:percentage, precision: 0) # => "100%"
|
48
|
+
# 1000.to_fs(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
|
49
|
+
# 302.24398923423.to_fs(:percentage, precision: 5) # => "302.24399%"
|
50
|
+
# 302.24398923423.to_fs(:percentage, round_mode: :down) # => "302.243%"
|
51
|
+
# 1000.to_fs(:percentage, locale: :fr) # => "1 000,000%"
|
52
|
+
# 100.to_fs(:percentage, format: '%n %') # => "100.000 %"
|
49
53
|
#
|
50
54
|
# Delimited:
|
51
|
-
# 12345678.
|
52
|
-
# 12345678.05.
|
53
|
-
# 12345678.
|
54
|
-
# 12345678.
|
55
|
-
# 12345678.05.
|
56
|
-
# 12345678.05.
|
57
|
-
# 98765432.98.
|
55
|
+
# 12345678.to_fs(:delimited) # => "12,345,678"
|
56
|
+
# 12345678.05.to_fs(:delimited) # => "12,345,678.05"
|
57
|
+
# 12345678.to_fs(:delimited, delimiter: '.') # => "12.345.678"
|
58
|
+
# 12345678.to_fs(:delimited, delimiter: ',') # => "12,345,678"
|
59
|
+
# 12345678.05.to_fs(:delimited, separator: ' ') # => "12,345,678 05"
|
60
|
+
# 12345678.05.to_fs(:delimited, locale: :fr) # => "12 345 678,05"
|
61
|
+
# 98765432.98.to_fs(:delimited, delimiter: ' ', separator: ',')
|
58
62
|
# # => "98 765 432,98"
|
59
63
|
#
|
60
64
|
# Rounded:
|
61
|
-
# 111.2345.
|
62
|
-
# 111.2345.
|
63
|
-
# 111.2345.
|
64
|
-
# 13.
|
65
|
-
# 389.32314.
|
66
|
-
# 111.2345.
|
67
|
-
# 111.2345.
|
68
|
-
# 13.
|
69
|
-
# 111.234.
|
70
|
-
# 13.
|
65
|
+
# 111.2345.to_fs(:rounded) # => "111.235"
|
66
|
+
# 111.2345.to_fs(:rounded, precision: 2) # => "111.23"
|
67
|
+
# 111.2345.to_fs(:rounded, precision: 2, round_mode: :up) # => "111.24"
|
68
|
+
# 13.to_fs(:rounded, precision: 5) # => "13.00000"
|
69
|
+
# 389.32314.to_fs(:rounded, precision: 0) # => "389"
|
70
|
+
# 111.2345.to_fs(:rounded, significant: true) # => "111"
|
71
|
+
# 111.2345.to_fs(:rounded, precision: 1, significant: true) # => "100"
|
72
|
+
# 13.to_fs(:rounded, precision: 5, significant: true) # => "13.000"
|
73
|
+
# 111.234.to_fs(:rounded, locale: :fr) # => "111,234"
|
74
|
+
# 13.to_fs(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
|
71
75
|
# # => "13"
|
72
|
-
# 389.32314.
|
73
|
-
# 1111.2345.
|
76
|
+
# 389.32314.to_fs(:rounded, precision: 4, significant: true) # => "389.3"
|
77
|
+
# 1111.2345.to_fs(:rounded, precision: 2, separator: ',', delimiter: '.')
|
74
78
|
# # => "1.111,23"
|
75
79
|
#
|
76
80
|
# Human-friendly size in Bytes:
|
77
|
-
# 123.
|
78
|
-
# 1234.
|
79
|
-
# 12345.
|
80
|
-
# 1234567.
|
81
|
-
# 1234567890.
|
82
|
-
# 1234567890123.
|
83
|
-
# 1234567890123456.
|
84
|
-
# 1234567890123456789.
|
85
|
-
# 1234567.
|
86
|
-
# 1234567.
|
87
|
-
# 483989.
|
88
|
-
# 1234567.
|
89
|
-
# 1234567890123.
|
90
|
-
# 524288000.
|
81
|
+
# 123.to_fs(:human_size) # => "123 Bytes"
|
82
|
+
# 1234.to_fs(:human_size) # => "1.21 KB"
|
83
|
+
# 12345.to_fs(:human_size) # => "12.1 KB"
|
84
|
+
# 1234567.to_fs(:human_size) # => "1.18 MB"
|
85
|
+
# 1234567890.to_fs(:human_size) # => "1.15 GB"
|
86
|
+
# 1234567890123.to_fs(:human_size) # => "1.12 TB"
|
87
|
+
# 1234567890123456.to_fs(:human_size) # => "1.1 PB"
|
88
|
+
# 1234567890123456789.to_fs(:human_size) # => "1.07 EB"
|
89
|
+
# 1234567.to_fs(:human_size, precision: 2) # => "1.2 MB"
|
90
|
+
# 1234567.to_fs(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
|
91
|
+
# 483989.to_fs(:human_size, precision: 2) # => "470 KB"
|
92
|
+
# 1234567.to_fs(:human_size, precision: 2, separator: ',') # => "1,2 MB"
|
93
|
+
# 1234567890123.to_fs(:human_size, precision: 5) # => "1.1228 TB"
|
94
|
+
# 524288000.to_fs(:human_size, precision: 5) # => "500 MB"
|
91
95
|
#
|
92
96
|
# Human-friendly format:
|
93
|
-
# 123.
|
94
|
-
# 1234.
|
95
|
-
# 12345.
|
96
|
-
# 1234567.
|
97
|
-
# 1234567890.
|
98
|
-
# 1234567890123.
|
99
|
-
# 1234567890123456.
|
100
|
-
# 1234567890123456789.
|
101
|
-
# 489939.
|
102
|
-
# 489939.
|
103
|
-
# 489939.
|
104
|
-
# 1234567.
|
105
|
-
# significant: false)
|
106
|
-
# 1234567.
|
97
|
+
# 123.to_fs(:human) # => "123"
|
98
|
+
# 1234.to_fs(:human) # => "1.23 Thousand"
|
99
|
+
# 12345.to_fs(:human) # => "12.3 Thousand"
|
100
|
+
# 1234567.to_fs(:human) # => "1.23 Million"
|
101
|
+
# 1234567890.to_fs(:human) # => "1.23 Billion"
|
102
|
+
# 1234567890123.to_fs(:human) # => "1.23 Trillion"
|
103
|
+
# 1234567890123456.to_fs(:human) # => "1.23 Quadrillion"
|
104
|
+
# 1234567890123456789.to_fs(:human) # => "1230 Quadrillion"
|
105
|
+
# 489939.to_fs(:human, precision: 2) # => "490 Thousand"
|
106
|
+
# 489939.to_fs(:human, precision: 2, round_mode: :down) # => "480 Thousand"
|
107
|
+
# 489939.to_fs(:human, precision: 4) # => "489.9 Thousand"
|
108
|
+
# 1234567.to_fs(:human, precision: 4,
|
109
|
+
# significant: false) # => "1.2346 Million"
|
110
|
+
# 1234567.to_fs(:human, precision: 1,
|
107
111
|
# separator: ',',
|
108
|
-
# significant: false)
|
109
|
-
def
|
112
|
+
# significant: false) # => "1,2 Million"
|
113
|
+
def to_fs(format = nil, options = nil)
|
114
|
+
return to_s if format.nil?
|
115
|
+
|
110
116
|
case format
|
111
|
-
when nil
|
112
|
-
super()
|
113
117
|
when Integer, String
|
114
|
-
|
118
|
+
to_s(format)
|
115
119
|
when :phone
|
116
120
|
ActiveSupport::NumberHelper.number_to_phone(self, options || {})
|
117
121
|
when :currency
|
@@ -127,11 +131,12 @@ module ActiveSupport
|
|
127
131
|
when :human_size
|
128
132
|
ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
|
129
133
|
when Symbol
|
130
|
-
|
134
|
+
to_s
|
131
135
|
else
|
132
|
-
|
136
|
+
to_s(format)
|
133
137
|
end
|
134
138
|
end
|
139
|
+
alias_method :to_formatted_s, :to_fs
|
135
140
|
end
|
136
141
|
end
|
137
142
|
|
@@ -1,11 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Object
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# <tt>
|
8
|
-
#
|
4
|
+
# Provides a way to check whether some class acts like some other class based on the existence of
|
5
|
+
# an appropriately-named marker method.
|
6
|
+
#
|
7
|
+
# A class that provides the same interface as <tt>SomeClass</tt> may define a marker method named
|
8
|
+
# <tt>acts_like_some_class?</tt> to signal its compatibility to callers of
|
9
|
+
# <tt>acts_like?(:some_class)</tt>.
|
10
|
+
#
|
11
|
+
# For example, Active Support extends <tt>Date</tt> to define an <tt>acts_like_date?</tt> method,
|
12
|
+
# and extends <tt>Time</tt> to define <tt>acts_like_time?</tt>. As a result, developers can call
|
13
|
+
# <tt>x.acts_like?(:time)</tt> and <tt>x.acts_like?(:date)</tt> to test duck-type compatibility,
|
14
|
+
# and classes that are able to act like <tt>Time</tt> can also define an <tt>acts_like_time?</tt>
|
15
|
+
# method to interoperate.
|
16
|
+
#
|
17
|
+
# Note that the marker method is only expected to exist. It isn't called, so its body or return
|
18
|
+
# value are irrelevant.
|
19
|
+
#
|
20
|
+
# ==== Example: A class that provides the same interface as <tt>String</tt>
|
21
|
+
#
|
22
|
+
# This class may define:
|
23
|
+
#
|
24
|
+
# class Stringish
|
25
|
+
# def acts_like_string?
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Then client code can query for duck-type-safeness this way:
|
30
|
+
#
|
31
|
+
# Stringish.new.acts_like?(:string) # => true
|
32
|
+
#
|
9
33
|
def acts_like?(duck)
|
10
34
|
case duck
|
11
35
|
when :time
|
@@ -131,7 +131,7 @@ class String
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
class Numeric
|
134
|
+
class Numeric # :nodoc:
|
135
135
|
# No number is blank:
|
136
136
|
#
|
137
137
|
# 1.blank? # => false
|
@@ -143,7 +143,7 @@ class Numeric #:nodoc:
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
class Time
|
146
|
+
class Time # :nodoc:
|
147
147
|
# No Time is blank:
|
148
148
|
#
|
149
149
|
# Time.now.blank? # => false
|
@@ -43,7 +43,7 @@ class Hash
|
|
43
43
|
def deep_dup
|
44
44
|
hash = dup
|
45
45
|
each_pair do |key, value|
|
46
|
-
if
|
46
|
+
if ::String === key || ::Symbol === key
|
47
47
|
hash[key] = value.deep_dup
|
48
48
|
else
|
49
49
|
hash.delete(key)
|
@@ -53,3 +53,19 @@ class Hash
|
|
53
53
|
hash
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
class Module
|
58
|
+
# Returns a copy of module or class if it's anonymous. If it's
|
59
|
+
# named, returns +self+.
|
60
|
+
#
|
61
|
+
# Object.deep_dup == Object # => true
|
62
|
+
# klass = Class.new
|
63
|
+
# klass.deep_dup == klass # => false
|
64
|
+
def deep_dup
|
65
|
+
if name.nil?
|
66
|
+
super
|
67
|
+
else
|
68
|
+
self
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -28,21 +28,41 @@ class Object
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
methods_are_duplicable = begin
|
32
|
+
Object.instance_method(:duplicable?).dup
|
33
|
+
true
|
34
|
+
rescue TypeError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
unless methods_are_duplicable
|
39
|
+
class Method
|
40
|
+
# Methods are not duplicable:
|
41
|
+
#
|
42
|
+
# method(:puts).duplicable? # => false
|
43
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
44
|
+
def duplicable?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class UnboundMethod
|
50
|
+
# Unbound methods are not duplicable:
|
51
|
+
#
|
52
|
+
# method(:puts).unbind.duplicable? # => false
|
53
|
+
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
54
|
+
def duplicable?
|
55
|
+
false
|
56
|
+
end
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
41
|
-
|
42
|
-
|
60
|
+
require "singleton"
|
61
|
+
|
62
|
+
module Singleton
|
63
|
+
# Singleton instances are not duplicable:
|
43
64
|
#
|
44
|
-
#
|
45
|
-
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
65
|
+
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
46
66
|
def duplicable?
|
47
67
|
false
|
48
68
|
end
|
@@ -1,16 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Object
|
4
|
-
# Returns true if this object is included in the argument.
|
5
|
-
#
|
4
|
+
# Returns true if this object is included in the argument.
|
5
|
+
#
|
6
|
+
# When argument is a +Range+, +#cover?+ is used to properly handle inclusion
|
7
|
+
# check within open ranges. Otherwise, argument must be any object which responds
|
8
|
+
# to +#include?+. Usage:
|
6
9
|
#
|
7
10
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
8
11
|
# "Konata".in?(characters) # => true
|
9
12
|
#
|
10
|
-
#
|
11
|
-
# to +#include?+.
|
13
|
+
# For non +Range+ arguments, this will throw an +ArgumentError+ if the argument
|
14
|
+
# doesn't respond to +#include?+.
|
12
15
|
def in?(another_object)
|
13
|
-
another_object
|
16
|
+
case another_object
|
17
|
+
when Range
|
18
|
+
another_object.cover?(self)
|
19
|
+
else
|
20
|
+
another_object.include?(self)
|
21
|
+
end
|
14
22
|
rescue NoMethodError
|
15
23
|
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
|
16
24
|
end
|
@@ -12,19 +12,29 @@ class Object
|
|
12
12
|
#
|
13
13
|
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
14
14
|
def instance_values
|
15
|
-
|
15
|
+
instance_variables.to_h do |ivar|
|
16
|
+
[ivar[1..-1].freeze, instance_variable_get(ivar)]
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
if Symbol.method_defined?(:name) # RUBY_VERSION >= "3.0"
|
21
|
+
# Returns an array of instance variable names as strings including "@".
|
22
|
+
#
|
23
|
+
# class C
|
24
|
+
# def initialize(x, y)
|
25
|
+
# @x, @y = x, y
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
30
|
+
def instance_variable_names
|
31
|
+
instance_variables.map(&:name)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
def instance_variable_names
|
35
|
+
variables = instance_variables
|
36
|
+
variables.map! { |s| s.to_s.freeze }
|
37
|
+
variables
|
38
|
+
end
|
29
39
|
end
|
30
40
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Hack to load
|
3
|
+
# Hack to load JSON gem first so we can override its to_json.
|
4
4
|
require "json"
|
5
5
|
require "bigdecimal"
|
6
|
+
require "ipaddr"
|
6
7
|
require "uri/generic"
|
7
8
|
require "pathname"
|
8
9
|
require "active_support/core_ext/big_decimal/conversions" # for #to_s
|
@@ -18,8 +19,7 @@ require "active_support/core_ext/date/conversions"
|
|
18
19
|
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
19
20
|
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
20
21
|
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
21
|
-
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
|
22
|
-
# 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.
|
23
23
|
#
|
24
24
|
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
25
25
|
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
@@ -29,7 +29,7 @@ require "active_support/core_ext/date/conversions"
|
|
29
29
|
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
|
30
30
|
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
31
31
|
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
32
|
-
# should give exactly the same results with or without
|
32
|
+
# should give exactly the same results with or without Active Support.
|
33
33
|
|
34
34
|
module ActiveSupport
|
35
35
|
module ToJsonWithActiveSupportEncoder # :nodoc:
|
@@ -49,8 +49,14 @@ end
|
|
49
49
|
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
50
50
|
end
|
51
51
|
|
52
|
+
class Module
|
53
|
+
def as_json(options = nil) # :nodoc:
|
54
|
+
name
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
52
58
|
class Object
|
53
|
-
def as_json(options = nil)
|
59
|
+
def as_json(options = nil) # :nodoc:
|
54
60
|
if respond_to?(:to_hash)
|
55
61
|
to_hash.as_json(options)
|
56
62
|
else
|
@@ -59,44 +65,52 @@ class Object
|
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
|
-
|
68
|
+
if RUBY_VERSION >= "3.2"
|
69
|
+
class Data # :nodoc:
|
70
|
+
def as_json(options = nil)
|
71
|
+
to_h.as_json(options)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Struct # :nodoc:
|
63
77
|
def as_json(options = nil)
|
64
|
-
|
78
|
+
to_h.as_json(options)
|
65
79
|
end
|
66
80
|
end
|
67
81
|
|
68
82
|
class TrueClass
|
69
|
-
def as_json(options = nil)
|
83
|
+
def as_json(options = nil) # :nodoc:
|
70
84
|
self
|
71
85
|
end
|
72
86
|
end
|
73
87
|
|
74
88
|
class FalseClass
|
75
|
-
def as_json(options = nil)
|
89
|
+
def as_json(options = nil) # :nodoc:
|
76
90
|
self
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
80
94
|
class NilClass
|
81
|
-
def as_json(options = nil)
|
95
|
+
def as_json(options = nil) # :nodoc:
|
82
96
|
self
|
83
97
|
end
|
84
98
|
end
|
85
99
|
|
86
100
|
class String
|
87
|
-
def as_json(options = nil)
|
101
|
+
def as_json(options = nil) # :nodoc:
|
88
102
|
self
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
92
106
|
class Symbol
|
93
|
-
def as_json(options = nil)
|
107
|
+
def as_json(options = nil) # :nodoc:
|
94
108
|
to_s
|
95
109
|
end
|
96
110
|
end
|
97
111
|
|
98
112
|
class Numeric
|
99
|
-
def as_json(options = nil)
|
113
|
+
def as_json(options = nil) # :nodoc:
|
100
114
|
self
|
101
115
|
end
|
102
116
|
end
|
@@ -104,7 +118,7 @@ end
|
|
104
118
|
class Float
|
105
119
|
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
106
120
|
# "Infinity" or "NaN" which are not valid JSON.
|
107
|
-
def as_json(options = nil)
|
121
|
+
def as_json(options = nil) # :nodoc:
|
108
122
|
finite? ? self : nil
|
109
123
|
end
|
110
124
|
end
|
@@ -119,43 +133,43 @@ class BigDecimal
|
|
119
133
|
# if the other end knows by contract that the data is supposed to be a
|
120
134
|
# BigDecimal, it still has the chance to post-process the string and get the
|
121
135
|
# real value.
|
122
|
-
def as_json(options = nil)
|
136
|
+
def as_json(options = nil) # :nodoc:
|
123
137
|
finite? ? to_s : nil
|
124
138
|
end
|
125
139
|
end
|
126
140
|
|
127
141
|
class Regexp
|
128
|
-
def as_json(options = nil)
|
142
|
+
def as_json(options = nil) # :nodoc:
|
129
143
|
to_s
|
130
144
|
end
|
131
145
|
end
|
132
146
|
|
133
147
|
module Enumerable
|
134
|
-
def as_json(options = nil)
|
148
|
+
def as_json(options = nil) # :nodoc:
|
135
149
|
to_a.as_json(options)
|
136
150
|
end
|
137
151
|
end
|
138
152
|
|
139
153
|
class IO
|
140
|
-
def as_json(options = nil)
|
154
|
+
def as_json(options = nil) # :nodoc:
|
141
155
|
to_s
|
142
156
|
end
|
143
157
|
end
|
144
158
|
|
145
159
|
class Range
|
146
|
-
def as_json(options = nil)
|
160
|
+
def as_json(options = nil) # :nodoc:
|
147
161
|
to_s
|
148
162
|
end
|
149
163
|
end
|
150
164
|
|
151
165
|
class Array
|
152
|
-
def as_json(options = nil)
|
166
|
+
def as_json(options = nil) # :nodoc:
|
153
167
|
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
154
168
|
end
|
155
169
|
end
|
156
170
|
|
157
171
|
class Hash
|
158
|
-
def as_json(options = nil)
|
172
|
+
def as_json(options = nil) # :nodoc:
|
159
173
|
# create a subset of the hash by applying :only or :except
|
160
174
|
subset = if options
|
161
175
|
if attrs = options[:only]
|
@@ -178,7 +192,7 @@ class Hash
|
|
178
192
|
end
|
179
193
|
|
180
194
|
class Time
|
181
|
-
def as_json(options = nil)
|
195
|
+
def as_json(options = nil) # :nodoc:
|
182
196
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
183
197
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
184
198
|
else
|
@@ -188,7 +202,7 @@ class Time
|
|
188
202
|
end
|
189
203
|
|
190
204
|
class Date
|
191
|
-
def as_json(options = nil)
|
205
|
+
def as_json(options = nil) # :nodoc:
|
192
206
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
193
207
|
strftime("%Y-%m-%d")
|
194
208
|
else
|
@@ -198,7 +212,7 @@ class Date
|
|
198
212
|
end
|
199
213
|
|
200
214
|
class DateTime
|
201
|
-
def as_json(options = nil)
|
215
|
+
def as_json(options = nil) # :nodoc:
|
202
216
|
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
203
217
|
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
204
218
|
else
|
@@ -207,19 +221,27 @@ class DateTime
|
|
207
221
|
end
|
208
222
|
end
|
209
223
|
|
210
|
-
class URI::Generic
|
224
|
+
class URI::Generic # :nodoc:
|
211
225
|
def as_json(options = nil)
|
212
226
|
to_s
|
213
227
|
end
|
214
228
|
end
|
215
229
|
|
216
|
-
class Pathname
|
230
|
+
class Pathname # :nodoc:
|
217
231
|
def as_json(options = nil)
|
218
232
|
to_s
|
219
233
|
end
|
220
234
|
end
|
221
235
|
|
222
|
-
|
236
|
+
unless IPAddr.method_defined?(:as_json, false)
|
237
|
+
class IPAddr # :nodoc:
|
238
|
+
def as_json(options = nil)
|
239
|
+
to_s
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
class Process::Status # :nodoc:
|
223
245
|
def as_json(options = nil)
|
224
246
|
{ exitstatus: exitstatus, pid: pid }
|
225
247
|
end
|
@@ -72,14 +72,12 @@ class Hash
|
|
72
72
|
#
|
73
73
|
# The string pairs "key=value" that conform the query string
|
74
74
|
# are sorted lexicographically in ascending order.
|
75
|
-
#
|
76
|
-
# This method is also aliased as +to_param+.
|
77
75
|
def to_query(namespace = nil)
|
78
|
-
query =
|
76
|
+
query = filter_map do |key, value|
|
79
77
|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
80
78
|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
81
79
|
end
|
82
|
-
end
|
80
|
+
end
|
83
81
|
|
84
82
|
query.sort! unless namespace.to_s.include?("[]")
|
85
83
|
query.join("&")
|