activesupport 4.2.11.1 → 5.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 +4 -4
- data/CHANGELOG.md +399 -440
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +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 +461 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +287 -196
- data/lib/active_support/callbacks.rb +640 -590
- data/lib/active_support/concern.rb +11 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +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/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +101 -33
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +14 -9
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +99 -29
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +41 -14
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +69 -21
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +8 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +6 -5
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +34 -38
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +85 -51
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +152 -161
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +307 -35
- 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 +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +123 -28
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +37 -13
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +163 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +11 -58
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +8 -7
- data/lib/active_support/logger_silence.rb +6 -4
- data/lib/active_support/logger_thread_safe_level.rb +7 -5
- data/lib/active_support/message_encryptor.rb +168 -53
- data/lib/active_support/message_verifier.rb +150 -17
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +36 -23
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +11 -9
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -5
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +21 -16
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +19 -47
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +81 -15
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +169 -39
- data/lib/active_support/values/time_zone.rb +196 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -114
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +37 -37
- data/lib/active_support.rb +12 -11
- metadata +54 -24
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,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
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToHumanSizeConverter < NumberConverter #:nodoc:
|
4
|
-
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
|
6
|
+
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
|
5
7
|
|
6
8
|
self.namespace = :human
|
7
9
|
self.validate_float = true
|
@@ -17,24 +19,24 @@ module ActiveSupport
|
|
17
19
|
if smaller_than_base?
|
18
20
|
number_to_format = number.to_i.to_s
|
19
21
|
else
|
20
|
-
human_size = number / (base
|
22
|
+
human_size = number / (base**exponent)
|
21
23
|
number_to_format = NumberToRoundedConverter.convert(human_size, options)
|
22
24
|
end
|
23
|
-
conversion_format.gsub(
|
25
|
+
conversion_format.gsub("%n".freeze, number_to_format).gsub("%u".freeze, unit)
|
24
26
|
end
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
30
|
def conversion_format
|
29
|
-
translate_number_value_with_default(
|
31
|
+
translate_number_value_with_default("human.storage_units.format", locale: options[:locale], raise: true)
|
30
32
|
end
|
31
33
|
|
32
34
|
def unit
|
33
|
-
translate_number_value_with_default(storage_unit_key, :
|
35
|
+
translate_number_value_with_default(storage_unit_key, locale: options[:locale], count: number.to_i, raise: true)
|
34
36
|
end
|
35
37
|
|
36
38
|
def storage_unit_key
|
37
|
-
key_end = smaller_than_base? ?
|
39
|
+
key_end = smaller_than_base? ? "byte" : STORAGE_UNITS[exponent]
|
38
40
|
"human.storage_units.units.#{key_end}"
|
39
41
|
end
|
40
42
|
|
@@ -50,9 +52,8 @@ module ActiveSupport
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def base
|
53
|
-
|
55
|
+
1024
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
58
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToPercentageConverter < NumberConverter # :nodoc:
|
@@ -5,7 +7,7 @@ module ActiveSupport
|
|
5
7
|
|
6
8
|
def convert
|
7
9
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
8
|
-
options[:format].gsub(
|
10
|
+
options[:format].gsub("%n".freeze, rounded_number)
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToPhoneConverter < NumberConverter #:nodoc:
|
4
6
|
def convert
|
5
|
-
str
|
7
|
+
str = country_code(opts[:country_code]).dup
|
6
8
|
str << convert_to_phone_number(number.to_s.strip)
|
7
9
|
str << phone_ext(opts[:extension])
|
8
10
|
end
|
@@ -18,12 +20,16 @@ module ActiveSupport
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def convert_with_area_code(number)
|
21
|
-
|
23
|
+
default_pattern = /(\d{1,3})(\d{3})(\d{4}$)/
|
24
|
+
number.gsub!(regexp_pattern(default_pattern),
|
25
|
+
"(\\1) \\2#{delimiter}\\3")
|
22
26
|
number
|
23
27
|
end
|
24
28
|
|
25
29
|
def convert_without_area_code(number)
|
26
|
-
|
30
|
+
default_pattern = /(\d{0,3})(\d{3})(\d{4})$/
|
31
|
+
number.gsub!(regexp_pattern(default_pattern),
|
32
|
+
"\\1#{delimiter}\\2#{delimiter}\\3")
|
27
33
|
number.slice!(0, 1) if start_with_delimiter?(number)
|
28
34
|
number
|
29
35
|
end
|
@@ -43,7 +49,10 @@ module ActiveSupport
|
|
43
49
|
def phone_ext(ext)
|
44
50
|
ext.blank? ? "" : " x #{ext}"
|
45
51
|
end
|
52
|
+
|
53
|
+
def regexp_pattern(default_pattern)
|
54
|
+
opts.fetch :pattern, default_pattern
|
55
|
+
end
|
46
56
|
end
|
47
57
|
end
|
48
58
|
end
|
49
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToRoundedConverter < NumberConverter # :nodoc:
|
@@ -5,63 +7,36 @@ module ActiveSupport
|
|
5
7
|
self.validate_float = true
|
6
8
|
|
7
9
|
def convert
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@number = number.to_d
|
18
|
-
end
|
10
|
+
helper = RoundingHelper.new(options)
|
11
|
+
rounded_number = helper.round(number)
|
12
|
+
|
13
|
+
if precision = options[:precision]
|
14
|
+
if options[:significant] && precision > 0
|
15
|
+
digits = helper.digit_count(rounded_number)
|
16
|
+
precision -= digits
|
17
|
+
precision = 0 if precision < 0 # don't let it be negative
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
formatted_string =
|
21
|
+
if BigDecimal === rounded_number && rounded_number.finite?
|
22
|
+
s = rounded_number.to_s("F")
|
23
|
+
s << "0".freeze * precision
|
24
|
+
a, b = s.split(".".freeze, 2)
|
25
|
+
a << ".".freeze
|
26
|
+
a << b[0, precision]
|
27
|
+
else
|
28
|
+
"%00.#{precision}f" % rounded_number
|
29
|
+
end
|
24
30
|
else
|
25
|
-
|
26
|
-
rounded_number = rounded_number.to_i if precision == 0 && rounded_number.finite?
|
27
|
-
rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
|
31
|
+
formatted_string = rounded_number
|
28
32
|
end
|
29
33
|
|
30
|
-
formatted_string =
|
31
|
-
if BigDecimal === rounded_number && rounded_number.finite?
|
32
|
-
s = rounded_number.to_s('F') + '0'*precision
|
33
|
-
a, b = s.split('.', 2)
|
34
|
-
a + '.' + b[0, precision]
|
35
|
-
else
|
36
|
-
"%00.#{precision}f" % rounded_number
|
37
|
-
end
|
38
|
-
|
39
34
|
delimited_number = NumberToDelimitedConverter.convert(formatted_string, options)
|
40
35
|
format_number(delimited_number)
|
41
36
|
end
|
42
37
|
|
43
38
|
private
|
44
39
|
|
45
|
-
def digits_and_rounded_number(precision)
|
46
|
-
if zero?
|
47
|
-
[1, 0]
|
48
|
-
else
|
49
|
-
digits = digit_count(number)
|
50
|
-
multiplier = 10 ** (digits - precision)
|
51
|
-
rounded_number = calculate_rounded_number(multiplier)
|
52
|
-
digits = digit_count(rounded_number) # After rounding, the number of digits may have changed
|
53
|
-
[digits, rounded_number]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def calculate_rounded_number(multiplier)
|
58
|
-
(number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
|
59
|
-
end
|
60
|
-
|
61
|
-
def digit_count(number)
|
62
|
-
number.zero? ? 1 : (Math.log10(absolute_number(number)) + 1).floor
|
63
|
-
end
|
64
|
-
|
65
40
|
def strip_insignificant_zeros
|
66
41
|
options[:strip_insignificant_zeros]
|
67
42
|
end
|
@@ -69,19 +44,11 @@ module ActiveSupport
|
|
69
44
|
def format_number(number)
|
70
45
|
if strip_insignificant_zeros
|
71
46
|
escaped_separator = Regexp.escape(options[:separator])
|
72
|
-
number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/,
|
47
|
+
number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, "")
|
73
48
|
else
|
74
49
|
number
|
75
50
|
end
|
76
51
|
end
|
77
|
-
|
78
|
-
def absolute_number(number)
|
79
|
-
number.respond_to?(:abs) ? number.abs : number.to_d.abs
|
80
|
-
end
|
81
|
-
|
82
|
-
def zero?
|
83
|
-
number.respond_to?(:zero?) ? number.zero? : number.to_d.zero?
|
84
|
-
end
|
85
52
|
end
|
86
53
|
end
|
87
54
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module NumberHelper
|
5
|
+
class RoundingHelper # :nodoc:
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def round(number)
|
13
|
+
return number unless precision
|
14
|
+
number = convert_to_decimal(number)
|
15
|
+
if significant && precision > 0
|
16
|
+
round_significant(number)
|
17
|
+
else
|
18
|
+
round_without_significant(number)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def digit_count(number)
|
23
|
+
return 1 if number.zero?
|
24
|
+
(Math.log10(absolute_number(number)) + 1).floor
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def round_without_significant(number)
|
29
|
+
number = number.round(precision)
|
30
|
+
number = number.to_i if precision == 0 && number.finite?
|
31
|
+
number = number.abs if number.zero? # prevent showing negative zeros
|
32
|
+
number
|
33
|
+
end
|
34
|
+
|
35
|
+
def round_significant(number)
|
36
|
+
return 0 if number.zero?
|
37
|
+
digits = digit_count(number)
|
38
|
+
multiplier = 10**(digits - precision)
|
39
|
+
(number / BigDecimal(multiplier.to_f.to_s)).round * multiplier
|
40
|
+
end
|
41
|
+
|
42
|
+
def convert_to_decimal(number)
|
43
|
+
case number
|
44
|
+
when Float, String
|
45
|
+
BigDecimal(number.to_s)
|
46
|
+
when Rational
|
47
|
+
BigDecimal(number, digit_count(number.to_i) + precision)
|
48
|
+
else
|
49
|
+
number.to_d
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def precision
|
54
|
+
options[:precision]
|
55
|
+
end
|
56
|
+
|
57
|
+
def significant
|
58
|
+
options[:significant]
|
59
|
+
end
|
60
|
+
|
61
|
+
def absolute_number(number)
|
62
|
+
number.respond_to?(:abs) ? number.abs : number.to_d.abs
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|