activesupport 4.2.0 → 5.2.0
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 +366 -232
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support.rb +17 -7
- 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.rb +271 -177
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- 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 +454 -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/callbacks.rb +654 -560
- data/lib/active_support/concern.rb +5 -3
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -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.rb +3 -1
- data/lib/active_support/core_ext/array.rb +9 -6
- 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/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/class.rb +4 -3
- 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 -8
- data/lib/active_support/core_ext/date.rb +6 -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 +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +31 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +179 -56
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time.rb +7 -4
- 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 +58 -20
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/enumerable.rb +107 -28
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/hash/compact.rb +24 -15
- data/lib/active_support/core_ext/hash/conversions.rb +63 -43
- 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 +16 -7
- data/lib/active_support/core_ext/integer.rb +5 -3
- 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 -33
- data/lib/active_support/core_ext/kernel.rb +6 -5
- 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 -83
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +13 -10
- data/lib/active_support/core_ext/module.rb +14 -11
- 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 +121 -39
- 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/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -38
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +29 -4
- 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 +98 -45
- 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 +6 -4
- data/lib/active_support/core_ext/object/try.rb +70 -22
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/range.rb +7 -4
- 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 +21 -19
- 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/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/string/access.rb +9 -7
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +8 -5
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +10 -8
- 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 +35 -35
- 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/time.rb +7 -5
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +101 -51
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- 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/uri.rb +5 -4
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies.rb +143 -160
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/deprecation/behaviors.rb +41 -12
- 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 +54 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +326 -30
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- 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 +128 -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 +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +130 -30
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +34 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +161 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +15 -57
- 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.rb +13 -10
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/logger.rb +54 -3
- data/lib/active_support/logger_silence.rb +12 -7
- data/lib/active_support/logger_thread_safe_level.rb +33 -0
- data/lib/active_support/message_encryptor.rb +173 -51
- 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.rb +4 -2
- data/lib/active_support/multibyte/chars.rb +37 -24
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/notifications/fanout.rb +10 -8
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/number_helper.rb +94 -68
- 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/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +22 -4
- data/lib/active_support/per_thread_registry.rb +13 -6
- 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 +17 -6
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +15 -14
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +18 -46
- 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 +12 -3
- 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 +96 -27
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +195 -53
- data/lib/active_support/values/time_zone.rb +200 -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.rb +69 -51
- data/lib/active_support/xml_mini/jdom.rb +116 -113
- data/lib/active_support/xml_mini/libxml.rb +17 -16
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +15 -15
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +17 -16
- metadata +55 -43
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
- 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 -11
- 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,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
extend ActiveSupport::Autoload
|
4
6
|
|
5
7
|
eager_autoload do
|
6
8
|
autoload :NumberConverter
|
9
|
+
autoload :RoundingHelper
|
7
10
|
autoload :NumberToRoundedConverter
|
8
11
|
autoload :NumberToDelimitedConverter
|
9
12
|
autoload :NumberToHumanConverter
|
@@ -15,7 +18,7 @@ module ActiveSupport
|
|
15
18
|
|
16
19
|
extend self
|
17
20
|
|
18
|
-
# Formats a +number+ into a
|
21
|
+
# Formats a +number+ into a phone number (US by default e.g., (555)
|
19
22
|
# 123-9876). You can customize the format in the +options+ hash.
|
20
23
|
#
|
21
24
|
# ==== Options
|
@@ -27,19 +30,26 @@ module ActiveSupport
|
|
27
30
|
# end of the generated number.
|
28
31
|
# * <tt>:country_code</tt> - Sets the country code for the phone
|
29
32
|
# number.
|
33
|
+
# * <tt>:pattern</tt> - Specifies how the number is divided into three
|
34
|
+
# groups with the custom regexp to override the default format.
|
30
35
|
# ==== Examples
|
31
36
|
#
|
32
|
-
# number_to_phone(5551234) # => 555-1234
|
33
|
-
# number_to_phone('5551234') # => 555-1234
|
34
|
-
# number_to_phone(1235551234) # => 123-555-1234
|
35
|
-
# number_to_phone(1235551234, area_code: true) # => (123) 555-1234
|
36
|
-
# number_to_phone(1235551234, delimiter: ' ') # => 123 555 1234
|
37
|
-
# number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
|
38
|
-
# number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234
|
39
|
-
# number_to_phone('123a456') # => 123a456
|
37
|
+
# number_to_phone(5551234) # => "555-1234"
|
38
|
+
# number_to_phone('5551234') # => "555-1234"
|
39
|
+
# number_to_phone(1235551234) # => "123-555-1234"
|
40
|
+
# number_to_phone(1235551234, area_code: true) # => "(123) 555-1234"
|
41
|
+
# number_to_phone(1235551234, delimiter: ' ') # => "123 555 1234"
|
42
|
+
# number_to_phone(1235551234, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
|
43
|
+
# number_to_phone(1235551234, country_code: 1) # => "+1-123-555-1234"
|
44
|
+
# number_to_phone('123a456') # => "123a456"
|
40
45
|
#
|
41
46
|
# number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
|
42
|
-
# # => +1.123.555.1234 x 1343
|
47
|
+
# # => "+1.123.555.1234 x 1343"
|
48
|
+
#
|
49
|
+
# number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
|
50
|
+
# # => "(755) 6123-4567"
|
51
|
+
# number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/)
|
52
|
+
# # => "133-1234-5678"
|
43
53
|
def number_to_phone(number, options = {})
|
44
54
|
NumberToPhoneConverter.convert(number, options)
|
45
55
|
end
|
@@ -47,6 +57,14 @@ module ActiveSupport
|
|
47
57
|
# Formats a +number+ into a currency string (e.g., $13.65). You
|
48
58
|
# can customize the format in the +options+ hash.
|
49
59
|
#
|
60
|
+
# The currency unit and number formatting of the current locale will be used
|
61
|
+
# unless otherwise specified in the provided options. No currency conversion
|
62
|
+
# is performed. If the user is given a way to change their locale, they will
|
63
|
+
# also be able to change the relative value of the currency displayed with
|
64
|
+
# this helper. If your application will ever support multiple locales, you
|
65
|
+
# may want to specify a constant <tt>:locale</tt> option or consider
|
66
|
+
# using a library capable of currency conversion.
|
67
|
+
#
|
50
68
|
# ==== Options
|
51
69
|
#
|
52
70
|
# * <tt>:locale</tt> - Sets the locale to be used for formatting
|
@@ -63,25 +81,25 @@ module ActiveSupport
|
|
63
81
|
# (defaults to "%u%n"). Fields are <tt>%u</tt> for the
|
64
82
|
# currency, and <tt>%n</tt> for the number.
|
65
83
|
# * <tt>:negative_format</tt> - Sets the format for negative
|
66
|
-
# numbers (defaults to prepending
|
84
|
+
# numbers (defaults to prepending a hyphen to the formatted
|
67
85
|
# number given by <tt>:format</tt>). Accepts the same fields
|
68
86
|
# than <tt>:format</tt>, except <tt>%n</tt> is here the
|
69
87
|
# absolute value of the number.
|
70
88
|
#
|
71
89
|
# ==== Examples
|
72
90
|
#
|
73
|
-
# number_to_currency(1234567890.50) # => $1,234,567,890.50
|
74
|
-
# number_to_currency(1234567890.506) # => $1,234,567,890.51
|
75
|
-
# number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
|
76
|
-
# number_to_currency(1234567890.506, locale: :fr) # => 1 234 567 890,51 €
|
77
|
-
# number_to_currency('123a456') # => $123a456
|
91
|
+
# number_to_currency(1234567890.50) # => "$1,234,567,890.50"
|
92
|
+
# number_to_currency(1234567890.506) # => "$1,234,567,890.51"
|
93
|
+
# number_to_currency(1234567890.506, precision: 3) # => "$1,234,567,890.506"
|
94
|
+
# number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
|
95
|
+
# number_to_currency('123a456') # => "$123a456"
|
78
96
|
#
|
79
97
|
# number_to_currency(-1234567890.50, negative_format: '(%u%n)')
|
80
|
-
# # => ($1,234,567,890.50)
|
98
|
+
# # => "($1,234,567,890.50)"
|
81
99
|
# number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '')
|
82
|
-
# # => £1234567890,50
|
100
|
+
# # => "£1234567890,50"
|
83
101
|
# number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '', format: '%n %u')
|
84
|
-
# # => 1234567890,50 £
|
102
|
+
# # => "1234567890,50 £"
|
85
103
|
def number_to_currency(number, options = {})
|
86
104
|
NumberToCurrencyConverter.convert(number, options)
|
87
105
|
end
|
@@ -94,9 +112,9 @@ module ActiveSupport
|
|
94
112
|
# * <tt>:locale</tt> - Sets the locale to be used for formatting
|
95
113
|
# (defaults to current locale).
|
96
114
|
# * <tt>:precision</tt> - Sets the precision of the number
|
97
|
-
# (defaults to 3).
|
98
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
99
|
-
# of significant_digits. If +false+, the
|
115
|
+
# (defaults to 3). Keeps the number's precision if +nil+.
|
116
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
117
|
+
# of significant_digits. If +false+, the number of fractional
|
100
118
|
# digits (defaults to +false+).
|
101
119
|
# * <tt>:separator</tt> - Sets the separator between the
|
102
120
|
# fractional and integer digits (defaults to ".").
|
@@ -110,14 +128,15 @@ module ActiveSupport
|
|
110
128
|
#
|
111
129
|
# ==== Examples
|
112
130
|
#
|
113
|
-
# number_to_percentage(100) # => 100.000%
|
114
|
-
# number_to_percentage('98') # => 98.000%
|
115
|
-
# number_to_percentage(100, precision: 0) # => 100%
|
116
|
-
# number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
|
117
|
-
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
|
118
|
-
# number_to_percentage(1000, locale: :fr) # =>
|
119
|
-
# number_to_percentage(
|
120
|
-
# number_to_percentage(
|
131
|
+
# number_to_percentage(100) # => "100.000%"
|
132
|
+
# number_to_percentage('98') # => "98.000%"
|
133
|
+
# number_to_percentage(100, precision: 0) # => "100%"
|
134
|
+
# number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
|
135
|
+
# number_to_percentage(302.24398923423, precision: 5) # => "302.24399%"
|
136
|
+
# number_to_percentage(1000, locale: :fr) # => "1000,000%"
|
137
|
+
# number_to_percentage(1000, precision: nil) # => "1000%"
|
138
|
+
# number_to_percentage('98a') # => "98a%"
|
139
|
+
# number_to_percentage(100, format: '%n %') # => "100.000 %"
|
121
140
|
def number_to_percentage(number, options = {})
|
122
141
|
NumberToPercentageConverter.convert(number, options)
|
123
142
|
end
|
@@ -134,19 +153,25 @@ module ActiveSupport
|
|
134
153
|
# to ",").
|
135
154
|
# * <tt>:separator</tt> - Sets the separator between the
|
136
155
|
# fractional and integer digits (defaults to ".").
|
156
|
+
# * <tt>:delimiter_pattern</tt> - Sets a custom regular expression used for
|
157
|
+
# deriving the placement of delimiter. Helpful when using currency formats
|
158
|
+
# like INR.
|
137
159
|
#
|
138
160
|
# ==== Examples
|
139
161
|
#
|
140
|
-
# number_to_delimited(12345678) # => 12,345,678
|
141
|
-
# number_to_delimited('123456') # => 123,456
|
142
|
-
# number_to_delimited(12345678.05) # => 12,345,678.05
|
143
|
-
# number_to_delimited(12345678, delimiter: '.') # => 12.345.678
|
144
|
-
# number_to_delimited(12345678, delimiter: ',') # => 12,345,678
|
145
|
-
# number_to_delimited(12345678.05, separator: ' ') # => 12,345,678 05
|
146
|
-
# number_to_delimited(12345678.05, locale: :fr) # => 12 345 678,05
|
147
|
-
# number_to_delimited('112a') # => 112a
|
162
|
+
# number_to_delimited(12345678) # => "12,345,678"
|
163
|
+
# number_to_delimited('123456') # => "123,456"
|
164
|
+
# number_to_delimited(12345678.05) # => "12,345,678.05"
|
165
|
+
# number_to_delimited(12345678, delimiter: '.') # => "12.345.678"
|
166
|
+
# number_to_delimited(12345678, delimiter: ',') # => "12,345,678"
|
167
|
+
# number_to_delimited(12345678.05, separator: ' ') # => "12,345,678 05"
|
168
|
+
# number_to_delimited(12345678.05, locale: :fr) # => "12 345 678,05"
|
169
|
+
# number_to_delimited('112a') # => "112a"
|
148
170
|
# number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
|
149
|
-
#
|
171
|
+
# # => "98 765 432,98"
|
172
|
+
# number_to_delimited("123456.78",
|
173
|
+
# delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)
|
174
|
+
# # => "1,23,456.78"
|
150
175
|
def number_to_delimited(number, options = {})
|
151
176
|
NumberToDelimitedConverter.convert(number, options)
|
152
177
|
end
|
@@ -161,9 +186,9 @@ module ActiveSupport
|
|
161
186
|
# * <tt>:locale</tt> - Sets the locale to be used for formatting
|
162
187
|
# (defaults to current locale).
|
163
188
|
# * <tt>:precision</tt> - Sets the precision of the number
|
164
|
-
# (defaults to 3).
|
165
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
166
|
-
# of significant_digits. If +false+, the
|
189
|
+
# (defaults to 3). Keeps the number's precision if +nil+.
|
190
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
191
|
+
# of significant_digits. If +false+, the number of fractional
|
167
192
|
# digits (defaults to +false+).
|
168
193
|
# * <tt>:separator</tt> - Sets the separator between the
|
169
194
|
# fractional and integer digits (defaults to ".").
|
@@ -175,21 +200,22 @@ module ActiveSupport
|
|
175
200
|
#
|
176
201
|
# ==== Examples
|
177
202
|
#
|
178
|
-
# number_to_rounded(111.2345) # => 111.235
|
179
|
-
# number_to_rounded(111.2345, precision: 2) # => 111.23
|
180
|
-
# number_to_rounded(13, precision: 5) # => 13.00000
|
181
|
-
# number_to_rounded(389.32314, precision: 0) # => 389
|
182
|
-
# number_to_rounded(111.2345, significant: true) # => 111
|
183
|
-
# number_to_rounded(111.2345, precision: 1, significant: true) # => 100
|
184
|
-
# number_to_rounded(13, precision: 5, significant: true) # => 13.000
|
185
|
-
# number_to_rounded(
|
203
|
+
# number_to_rounded(111.2345) # => "111.235"
|
204
|
+
# number_to_rounded(111.2345, precision: 2) # => "111.23"
|
205
|
+
# number_to_rounded(13, precision: 5) # => "13.00000"
|
206
|
+
# number_to_rounded(389.32314, precision: 0) # => "389"
|
207
|
+
# number_to_rounded(111.2345, significant: true) # => "111"
|
208
|
+
# number_to_rounded(111.2345, precision: 1, significant: true) # => "100"
|
209
|
+
# number_to_rounded(13, precision: 5, significant: true) # => "13.000"
|
210
|
+
# number_to_rounded(13, precision: nil) # => "13"
|
211
|
+
# number_to_rounded(111.234, locale: :fr) # => "111,234"
|
186
212
|
#
|
187
213
|
# number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
|
188
|
-
# # => 13
|
214
|
+
# # => "13"
|
189
215
|
#
|
190
|
-
# number_to_rounded(389.32314, precision: 4, significant: true) # => 389.3
|
216
|
+
# number_to_rounded(389.32314, precision: 4, significant: true) # => "389.3"
|
191
217
|
# number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
|
192
|
-
# # => 1.111,23
|
218
|
+
# # => "1.111,23"
|
193
219
|
def number_to_rounded(number, options = {})
|
194
220
|
NumberToRoundedConverter.convert(number, options)
|
195
221
|
end
|
@@ -208,8 +234,8 @@ module ActiveSupport
|
|
208
234
|
# (defaults to current locale).
|
209
235
|
# * <tt>:precision</tt> - Sets the precision of the number
|
210
236
|
# (defaults to 3).
|
211
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
212
|
-
# of significant_digits. If +false+, the
|
237
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
238
|
+
# of significant_digits. If +false+, the number of fractional
|
213
239
|
# digits (defaults to +true+)
|
214
240
|
# * <tt>:separator</tt> - Sets the separator between the
|
215
241
|
# fractional and integer digits (defaults to ".").
|
@@ -218,20 +244,20 @@ module ActiveSupport
|
|
218
244
|
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
|
219
245
|
# insignificant zeros after the decimal separator (defaults to
|
220
246
|
# +true+)
|
221
|
-
# * <tt>:prefix</tt> - If +:si+ formats the number using the SI
|
222
|
-
# prefix (defaults to :binary)
|
223
247
|
#
|
224
248
|
# ==== Examples
|
225
249
|
#
|
226
|
-
# number_to_human_size(123) # => 123 Bytes
|
227
|
-
# number_to_human_size(1234) # => 1.21 KB
|
228
|
-
# number_to_human_size(12345) # => 12.1 KB
|
229
|
-
# number_to_human_size(1234567) # => 1.18 MB
|
230
|
-
# number_to_human_size(1234567890) # => 1.15 GB
|
231
|
-
# number_to_human_size(1234567890123) # => 1.12 TB
|
232
|
-
# number_to_human_size(
|
233
|
-
# number_to_human_size(
|
234
|
-
# number_to_human_size(1234567, precision: 2
|
250
|
+
# number_to_human_size(123) # => "123 Bytes"
|
251
|
+
# number_to_human_size(1234) # => "1.21 KB"
|
252
|
+
# number_to_human_size(12345) # => "12.1 KB"
|
253
|
+
# number_to_human_size(1234567) # => "1.18 MB"
|
254
|
+
# number_to_human_size(1234567890) # => "1.15 GB"
|
255
|
+
# number_to_human_size(1234567890123) # => "1.12 TB"
|
256
|
+
# number_to_human_size(1234567890123456) # => "1.1 PB"
|
257
|
+
# number_to_human_size(1234567890123456789) # => "1.07 EB"
|
258
|
+
# number_to_human_size(1234567, precision: 2) # => "1.2 MB"
|
259
|
+
# number_to_human_size(483989, precision: 2) # => "470 KB"
|
260
|
+
# number_to_human_size(1234567, precision: 2, separator: ',') # => "1,2 MB"
|
235
261
|
# number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
|
236
262
|
# number_to_human_size(524288000, precision: 5) # => "500 MB"
|
237
263
|
def number_to_human_size(number, options = {})
|
@@ -258,8 +284,8 @@ module ActiveSupport
|
|
258
284
|
# (defaults to current locale).
|
259
285
|
# * <tt>:precision</tt> - Sets the precision of the number
|
260
286
|
# (defaults to 3).
|
261
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
262
|
-
# of significant_digits. If +false+, the
|
287
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
288
|
+
# of significant_digits. If +false+, the number of fractional
|
263
289
|
# digits (defaults to +true+)
|
264
290
|
# * <tt>:separator</tt> - Sets the separator between the
|
265
291
|
# fractional and integer digits (defaults to ".").
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/big_decimal/conversions"
|
4
|
+
require "active_support/core_ext/object/blank"
|
5
|
+
require "active_support/core_ext/hash/keys"
|
6
|
+
require "active_support/i18n"
|
7
|
+
require "active_support/core_ext/class/attribute"
|
6
8
|
|
7
9
|
module ActiveSupport
|
8
10
|
module NumberHelper
|
@@ -139,17 +141,17 @@ module ActiveSupport
|
|
139
141
|
@options ||= format_options.merge(opts)
|
140
142
|
end
|
141
143
|
|
142
|
-
def format_options
|
144
|
+
def format_options
|
143
145
|
default_format_options.merge!(i18n_format_options)
|
144
146
|
end
|
145
147
|
|
146
|
-
def default_format_options
|
148
|
+
def default_format_options
|
147
149
|
options = DEFAULTS[:format].dup
|
148
150
|
options.merge!(DEFAULTS[namespace][:format]) if namespace
|
149
151
|
options
|
150
152
|
end
|
151
153
|
|
152
|
-
def i18n_format_options
|
154
|
+
def i18n_format_options
|
153
155
|
locale = opts[:locale]
|
154
156
|
options = I18n.translate(:'number.format', locale: locale, default: {}).dup
|
155
157
|
|
@@ -160,7 +162,7 @@ module ActiveSupport
|
|
160
162
|
options
|
161
163
|
end
|
162
164
|
|
163
|
-
def translate_number_value_with_default(key, i18n_options = {})
|
165
|
+
def translate_number_value_with_default(key, i18n_options = {})
|
164
166
|
I18n.translate(key, { default: default_value(key), scope: :number }.merge!(i18n_options))
|
165
167
|
end
|
166
168
|
|
@@ -169,10 +171,10 @@ module ActiveSupport
|
|
169
171
|
end
|
170
172
|
|
171
173
|
def default_value(key)
|
172
|
-
key.split(
|
174
|
+
key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
|
173
175
|
end
|
174
176
|
|
175
|
-
def valid_float?
|
177
|
+
def valid_float?
|
176
178
|
Float(number)
|
177
179
|
rescue ArgumentError, TypeError
|
178
180
|
false
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/numeric/inquiry"
|
4
|
+
|
1
5
|
module ActiveSupport
|
2
6
|
module NumberHelper
|
3
7
|
class NumberToCurrencyConverter < NumberConverter # :nodoc:
|
@@ -7,36 +11,32 @@ module ActiveSupport
|
|
7
11
|
number = self.number.to_s.strip
|
8
12
|
format = options[:format]
|
9
13
|
|
10
|
-
if
|
14
|
+
if number.to_f.negative?
|
11
15
|
format = options[:negative_format]
|
12
16
|
number = absolute_value(number)
|
13
17
|
end
|
14
18
|
|
15
19
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
16
|
-
format.gsub(
|
20
|
+
format.gsub("%n".freeze, rounded_number).gsub("%u".freeze, options[:unit])
|
17
21
|
end
|
18
22
|
|
19
23
|
private
|
20
24
|
|
21
|
-
def is_negative?(number)
|
22
|
-
number.to_f.phase != 0
|
23
|
-
end
|
24
|
-
|
25
25
|
def absolute_value(number)
|
26
|
-
number.respond_to?(
|
26
|
+
number.respond_to?(:abs) ? number.abs : number.sub(/\A-/, "")
|
27
27
|
end
|
28
28
|
|
29
29
|
def options
|
30
30
|
@options ||= begin
|
31
31
|
defaults = default_format_options.merge(i18n_opts)
|
32
|
-
# Override negative format if format options
|
32
|
+
# Override negative format if format options are given
|
33
33
|
defaults[:negative_format] = "-#{opts[:format]}" if opts[:format]
|
34
34
|
defaults.merge!(opts)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def i18n_opts
|
39
|
-
# Set International negative format if not
|
39
|
+
# Set International negative format if it does not exist
|
40
40
|
i18n = i18n_format_options
|
41
41
|
i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format]
|
42
42
|
i18n
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToDelimitedConverter < NumberConverter #:nodoc:
|
4
6
|
self.validate_float = true
|
5
7
|
|
6
|
-
|
8
|
+
DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
|
7
9
|
|
8
10
|
def convert
|
9
11
|
parts.join(options[:separator])
|
@@ -12,12 +14,16 @@ module ActiveSupport
|
|
12
14
|
private
|
13
15
|
|
14
16
|
def parts
|
15
|
-
left, right = number.to_s.split(
|
16
|
-
left.gsub!(
|
17
|
+
left, right = number.to_s.split(".".freeze)
|
18
|
+
left.gsub!(delimiter_pattern) do |digit_to_delimit|
|
17
19
|
"#{digit_to_delimit}#{options[:delimiter]}"
|
18
20
|
end
|
19
21
|
[left, right].compact
|
20
22
|
end
|
23
|
+
|
24
|
+
def delimiter_pattern
|
25
|
+
options.fetch(:delimiter_pattern, DEFAULT_DELIMITER_REGEX)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToHumanConverter < NumberConverter # :nodoc:
|
@@ -9,6 +11,7 @@ module ActiveSupport
|
|
9
11
|
self.validate_float = true
|
10
12
|
|
11
13
|
def convert # :nodoc:
|
14
|
+
@number = RoundingHelper.new(options).round(number)
|
12
15
|
@number = Float(number)
|
13
16
|
|
14
17
|
# for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
|
@@ -18,27 +21,26 @@ module ActiveSupport
|
|
18
21
|
|
19
22
|
units = opts[:units]
|
20
23
|
exponent = calculate_exponent(units)
|
21
|
-
@number = number / (10
|
22
|
-
|
23
|
-
unit = determine_unit(units, exponent)
|
24
|
+
@number = number / (10**exponent)
|
24
25
|
|
25
26
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
26
|
-
|
27
|
+
unit = determine_unit(units, exponent)
|
28
|
+
format.gsub("%n".freeze, rounded_number).gsub("%u".freeze, unit).strip
|
27
29
|
end
|
28
30
|
|
29
31
|
private
|
30
32
|
|
31
33
|
def format
|
32
|
-
options[:format] || translate_in_locale(
|
34
|
+
options[:format] || translate_in_locale("human.decimal_units.format")
|
33
35
|
end
|
34
36
|
|
35
37
|
def determine_unit(units, exponent)
|
36
38
|
exp = DECIMAL_UNITS[exponent]
|
37
39
|
case units
|
38
40
|
when Hash
|
39
|
-
units[exp] ||
|
41
|
+
units[exp] || ""
|
40
42
|
when String, Symbol
|
41
|
-
I18n.translate("#{units}.#{exp}", :
|
43
|
+
I18n.translate("#{units}.#{exp}", locale: options[:locale], count: number.to_i)
|
42
44
|
else
|
43
45
|
translate_in_locale("human.decimal_units.units.#{exp}", count: number.to_i)
|
44
46
|
end
|
@@ -54,12 +56,12 @@ module ActiveSupport
|
|
54
56
|
when Hash
|
55
57
|
units
|
56
58
|
when String, Symbol
|
57
|
-
I18n.translate(units.to_s, :
|
59
|
+
I18n.translate(units.to_s, locale: options[:locale], raise: true)
|
58
60
|
when nil
|
59
61
|
translate_in_locale("human.decimal_units.units", raise: true)
|
60
62
|
else
|
61
63
|
raise ArgumentError, ":units must be a Hash or String translation scope."
|
62
|
-
end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by
|
64
|
+
end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by(&:-@)
|
63
65
|
end
|
64
66
|
end
|
65
67
|
end
|