activesupport 4.2.0 → 5.0.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 +4 -4
- data/CHANGELOG.md +630 -220
- data/MIT-LICENSE +2 -2
- data/README.rdoc +2 -3
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +36 -22
- data/lib/active_support/cache/mem_cache_store.rb +63 -54
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/cache.rb +73 -89
- data/lib/active_support/callbacks.rb +195 -155
- data/lib/active_support/concern.rb +2 -2
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +27 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/grouping.rb +9 -18
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +3 -4
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +13 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +109 -25
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -10
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -1
- data/lib/active_support/core_ext/enumerable.rb +49 -5
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +23 -4
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +23 -19
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
- data/lib/active_support/core_ext/integer/time.rb +1 -16
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -83
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +12 -11
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +35 -25
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +4 -0
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -11
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +74 -64
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +24 -19
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +17 -5
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +8 -13
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +15 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +68 -22
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +4 -3
- data/lib/active_support/core_ext/string/filters.rb +5 -5
- data/lib/active_support/core_ext/string/inflections.rb +32 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +18 -16
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time/calculations.rb +36 -11
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +36 -4
- data/lib/active_support/core_ext/time.rb +1 -1
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +87 -95
- data/lib/active_support/deprecation/behaviors.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +23 -5
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +55 -10
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +23 -3
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +46 -13
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +97 -90
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +11 -10
- data/lib/active_support/json/encoding.rb +4 -49
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/logger.rb +50 -1
- data/lib/active_support/logger_silence.rb +8 -4
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +4 -4
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +13 -4
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +6 -6
- data/lib/active_support/notifications/instrumenter.rb +20 -2
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
- data/lib/active_support/number_helper.rb +90 -67
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +8 -3
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +93 -47
- data/lib/active_support/security_utils.rb +7 -0
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +15 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +13 -10
- data/lib/active_support/time_with_zone.rb +135 -46
- data/lib/active_support/values/time_zone.rb +95 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +7 -6
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +7 -8
- data/lib/active_support/xml_mini.rb +22 -14
- data/lib/active_support.rb +20 -6
- metadata +32 -35
- 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/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
module ActiveSupport
|
3
2
|
module Multibyte
|
4
3
|
module Unicode
|
@@ -11,7 +10,7 @@ module ActiveSupport
|
|
11
10
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
12
11
|
|
13
12
|
# The Unicode version that is supported by the implementation
|
14
|
-
UNICODE_VERSION = '
|
13
|
+
UNICODE_VERSION = '8.0.0'
|
15
14
|
|
16
15
|
# The default normalization used for operations that require
|
17
16
|
# normalization. It can be set to any of the normalizations
|
@@ -58,7 +57,7 @@ module ActiveSupport
|
|
58
57
|
# Returns a regular expression pattern that matches the passed Unicode
|
59
58
|
# codepoints.
|
60
59
|
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
|
61
|
-
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
|
60
|
+
array_of_codepoints.collect{ |e| [e].pack 'U*'.freeze }.join('|'.freeze)
|
62
61
|
end
|
63
62
|
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
|
64
63
|
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
|
@@ -88,19 +87,44 @@ module ActiveSupport
|
|
88
87
|
pos += 1
|
89
88
|
previous = codepoints[pos-1]
|
90
89
|
current = codepoints[pos]
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
)
|
103
|
-
|
90
|
+
|
91
|
+
should_break =
|
92
|
+
# GB3. CR X LF
|
93
|
+
if previous == database.boundary[:cr] and current == database.boundary[:lf]
|
94
|
+
false
|
95
|
+
# GB4. (Control|CR|LF) ÷
|
96
|
+
elsif previous and in_char_class?(previous, [:control,:cr,:lf])
|
97
|
+
true
|
98
|
+
# GB5. ÷ (Control|CR|LF)
|
99
|
+
elsif in_char_class?(current, [:control,:cr,:lf])
|
100
|
+
true
|
101
|
+
# GB6. L X (L|V|LV|LVT)
|
102
|
+
elsif database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt])
|
103
|
+
false
|
104
|
+
# GB7. (LV|V) X (V|T)
|
105
|
+
elsif in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t])
|
106
|
+
false
|
107
|
+
# GB8. (LVT|T) X (T)
|
108
|
+
elsif in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current
|
109
|
+
false
|
110
|
+
# GB8a. Regional_Indicator X Regional_Indicator
|
111
|
+
elsif database.boundary[:regional_indicator] === previous and database.boundary[:regional_indicator] === current
|
112
|
+
false
|
113
|
+
# GB9. X Extend
|
114
|
+
elsif database.boundary[:extend] === current
|
115
|
+
false
|
116
|
+
# GB9a. X SpacingMark
|
117
|
+
elsif database.boundary[:spacingmark] === current
|
118
|
+
false
|
119
|
+
# GB9b. Prepend X
|
120
|
+
elsif database.boundary[:prepend] === previous
|
121
|
+
false
|
122
|
+
# GB10. Any ÷ Any
|
123
|
+
else
|
124
|
+
true
|
125
|
+
end
|
126
|
+
|
127
|
+
if should_break
|
104
128
|
unpacked << codepoints[marker..pos-1]
|
105
129
|
marker = pos
|
106
130
|
end
|
@@ -211,9 +235,8 @@ module ActiveSupport
|
|
211
235
|
codepoints
|
212
236
|
end
|
213
237
|
|
214
|
-
# Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
|
215
238
|
# Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
|
216
|
-
if
|
239
|
+
if !defined?(Rubinius)
|
217
240
|
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
218
241
|
# resulting in a valid UTF-8 string.
|
219
242
|
#
|
@@ -258,7 +281,7 @@ module ActiveSupport
|
|
258
281
|
# * <tt>string</tt> - The string to perform normalization on.
|
259
282
|
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
260
283
|
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
261
|
-
# Default is ActiveSupport::Multibyte.default_normalization_form.
|
284
|
+
# Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
|
262
285
|
def normalize(string, form=nil)
|
263
286
|
form ||= @default_normalization_form
|
264
287
|
# See http://www.unicode.org/reports/tr15, Table 1
|
@@ -274,7 +297,7 @@ module ActiveSupport
|
|
274
297
|
compose(reorder_characters(decompose(:compatibility, codepoints)))
|
275
298
|
else
|
276
299
|
raise ArgumentError, "#{form} is not a valid normalization variant", caller
|
277
|
-
end.pack('U*')
|
300
|
+
end.pack('U*'.freeze)
|
278
301
|
end
|
279
302
|
|
280
303
|
def downcase(string)
|
@@ -339,7 +362,7 @@ module ActiveSupport
|
|
339
362
|
end
|
340
363
|
|
341
364
|
# Redefine the === method so we can write shorter rules for grapheme cluster breaks
|
342
|
-
@boundary.
|
365
|
+
@boundary.each_key do |k|
|
343
366
|
@boundary[k].instance_eval do
|
344
367
|
def ===(other)
|
345
368
|
detect { |i| i === other } ? true : false
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'mutex_m'
|
2
|
-
require '
|
2
|
+
require 'concurrent/map'
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
module Notifications
|
@@ -12,7 +12,7 @@ module ActiveSupport
|
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
@subscribers = []
|
15
|
-
@listeners_for =
|
15
|
+
@listeners_for = Concurrent::Map.new
|
16
16
|
super
|
17
17
|
end
|
18
18
|
|
@@ -42,8 +42,8 @@ module ActiveSupport
|
|
42
42
|
listeners_for(name).each { |s| s.start(name, id, payload) }
|
43
43
|
end
|
44
44
|
|
45
|
-
def finish(name, id, payload)
|
46
|
-
|
45
|
+
def finish(name, id, payload, listeners = listeners_for(name))
|
46
|
+
listeners.each { |s| s.finish(name, id, payload) }
|
47
47
|
end
|
48
48
|
|
49
49
|
def publish(name, *args)
|
@@ -51,7 +51,7 @@ module ActiveSupport
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def listeners_for(name)
|
54
|
-
# this is correctly done double-checked locking (
|
54
|
+
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
|
55
55
|
@listeners_for[name] || synchronize do
|
56
56
|
# use synchronisation when accessing @subscribers
|
57
57
|
@listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
|
@@ -111,7 +111,7 @@ module ActiveSupport
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
class Timed < Evented
|
114
|
+
class Timed < Evented # :nodoc:
|
115
115
|
def publish(name, *args)
|
116
116
|
@delegate.call name, *args
|
117
117
|
end
|
@@ -15,14 +15,16 @@ module ActiveSupport
|
|
15
15
|
# and publish it. Notice that events get sent even if an error occurs
|
16
16
|
# in the passed-in block.
|
17
17
|
def instrument(name, payload={})
|
18
|
-
|
18
|
+
# some of the listeners might have state
|
19
|
+
listeners_state = start name, payload
|
19
20
|
begin
|
20
21
|
yield payload
|
21
22
|
rescue Exception => e
|
22
23
|
payload[:exception] = [e.class.name, e.message]
|
24
|
+
payload[:exception_object] = e
|
23
25
|
raise e
|
24
26
|
ensure
|
25
|
-
|
27
|
+
finish_with_state listeners_state, name, payload
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
@@ -36,6 +38,10 @@ module ActiveSupport
|
|
36
38
|
@notifier.finish name, @id, payload
|
37
39
|
end
|
38
40
|
|
41
|
+
def finish_with_state(listeners_state, name, payload)
|
42
|
+
@notifier.finish name, @id, payload, listeners_state
|
43
|
+
end
|
44
|
+
|
39
45
|
private
|
40
46
|
|
41
47
|
def unique_id
|
@@ -57,6 +63,18 @@ module ActiveSupport
|
|
57
63
|
@duration = nil
|
58
64
|
end
|
59
65
|
|
66
|
+
# Returns the difference in milliseconds between when the execution of the
|
67
|
+
# event started and when it ended.
|
68
|
+
#
|
69
|
+
# ActiveSupport::Notifications.subscribe('wait') do |*args|
|
70
|
+
# @event = ActiveSupport::Notifications::Event.new(*args)
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# ActiveSupport::Notifications.instrument('wait') do
|
74
|
+
# sleep 1
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# @event.duration # => 1000.138
|
60
78
|
def duration
|
61
79
|
@duration ||= 1000.0 * (self.end - time)
|
62
80
|
end
|
@@ -69,8 +69,8 @@ module ActiveSupport
|
|
69
69
|
# is able to take the arguments as they come and provide an object-oriented
|
70
70
|
# interface to that data.
|
71
71
|
#
|
72
|
-
# It is also possible to pass an object
|
73
|
-
# <tt>subscribe</tt> method instead of a block:
|
72
|
+
# It is also possible to pass an object which responds to <tt>call</tt> method
|
73
|
+
# as the second parameter to the <tt>subscribe</tt> method instead of a block:
|
74
74
|
#
|
75
75
|
# module ActionController
|
76
76
|
# class PageRequest
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/numeric/inquiry'
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module NumberHelper
|
3
5
|
class NumberToCurrencyConverter < NumberConverter # :nodoc:
|
@@ -7,36 +9,32 @@ module ActiveSupport
|
|
7
9
|
number = self.number.to_s.strip
|
8
10
|
format = options[:format]
|
9
11
|
|
10
|
-
if
|
12
|
+
if number.to_f.negative?
|
11
13
|
format = options[:negative_format]
|
12
14
|
number = absolute_value(number)
|
13
15
|
end
|
14
16
|
|
15
17
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
16
|
-
format.gsub(
|
18
|
+
format.gsub('%n'.freeze, rounded_number).gsub('%u'.freeze, options[:unit])
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
def is_negative?(number)
|
22
|
-
number.to_f.phase != 0
|
23
|
-
end
|
24
|
-
|
25
23
|
def absolute_value(number)
|
26
|
-
number.respond_to?(
|
24
|
+
number.respond_to?(:abs) ? number.abs : number.sub(/\A-/, '')
|
27
25
|
end
|
28
26
|
|
29
27
|
def options
|
30
28
|
@options ||= begin
|
31
29
|
defaults = default_format_options.merge(i18n_opts)
|
32
|
-
# Override negative format if format options
|
30
|
+
# Override negative format if format options are given
|
33
31
|
defaults[:negative_format] = "-#{opts[:format]}" if opts[:format]
|
34
32
|
defaults.merge!(opts)
|
35
33
|
end
|
36
34
|
end
|
37
35
|
|
38
36
|
def i18n_opts
|
39
|
-
# Set International negative format if not
|
37
|
+
# Set International negative format if it does not exist
|
40
38
|
i18n = i18n_format_options
|
41
39
|
i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format]
|
42
40
|
i18n
|
@@ -3,7 +3,7 @@ module ActiveSupport
|
|
3
3
|
class NumberToDelimitedConverter < NumberConverter #:nodoc:
|
4
4
|
self.validate_float = true
|
5
5
|
|
6
|
-
|
6
|
+
DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
|
7
7
|
|
8
8
|
def convert
|
9
9
|
parts.join(options[:separator])
|
@@ -12,12 +12,17 @@ module ActiveSupport
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def parts
|
15
|
-
left, right = number.to_s.split('.')
|
16
|
-
left.gsub!(
|
15
|
+
left, right = number.to_s.split('.'.freeze)
|
16
|
+
left.gsub!(delimiter_pattern) do |digit_to_delimit|
|
17
17
|
"#{digit_to_delimit}#{options[:delimiter]}"
|
18
18
|
end
|
19
19
|
[left, right].compact
|
20
20
|
end
|
21
|
+
|
22
|
+
def delimiter_pattern
|
23
|
+
options.fetch(:delimiter_pattern, DEFAULT_DELIMITER_REGEX)
|
24
|
+
end
|
25
|
+
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
@@ -20,10 +20,12 @@ module ActiveSupport
|
|
20
20
|
exponent = calculate_exponent(units)
|
21
21
|
@number = number / (10 ** exponent)
|
22
22
|
|
23
|
+
until (rounded_number = NumberToRoundedConverter.convert(number, options)) != NumberToRoundedConverter.convert(1000, options)
|
24
|
+
@number = number / 1000.0
|
25
|
+
exponent += 3
|
26
|
+
end
|
23
27
|
unit = determine_unit(units, exponent)
|
24
|
-
|
25
|
-
rounded_number = NumberToRoundedConverter.convert(number, options)
|
26
|
-
format.gsub(/%n/, rounded_number).gsub(/%u/, unit).strip
|
28
|
+
format.gsub('%n'.freeze, rounded_number).gsub('%u'.freeze, unit).strip
|
27
29
|
end
|
28
30
|
|
29
31
|
private
|
@@ -59,7 +61,7 @@ module ActiveSupport
|
|
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,12 +1,16 @@
|
|
1
1
|
module ActiveSupport
|
2
2
|
module NumberHelper
|
3
3
|
class NumberToHumanSizeConverter < NumberConverter #:nodoc:
|
4
|
-
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
|
4
|
+
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
|
5
5
|
|
6
6
|
self.namespace = :human
|
7
7
|
self.validate_float = true
|
8
8
|
|
9
9
|
def convert
|
10
|
+
if opts.key?(:prefix)
|
11
|
+
ActiveSupport::Deprecation.warn('The :prefix option of `number_to_human_size` is deprecated and will be removed in Rails 5.1 with no replacement.')
|
12
|
+
end
|
13
|
+
|
10
14
|
@number = Float(number)
|
11
15
|
|
12
16
|
# for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
|
@@ -20,7 +24,7 @@ module ActiveSupport
|
|
20
24
|
human_size = number / (base ** exponent)
|
21
25
|
number_to_format = NumberToRoundedConverter.convert(human_size, options)
|
22
26
|
end
|
23
|
-
conversion_format.gsub(
|
27
|
+
conversion_format.gsub('%n'.freeze, number_to_format).gsub('%u'.freeze, unit)
|
24
28
|
end
|
25
29
|
|
26
30
|
private
|
@@ -18,12 +18,16 @@ module ActiveSupport
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def convert_with_area_code(number)
|
21
|
-
|
21
|
+
default_pattern = /(\d{1,3})(\d{3})(\d{4}$)/
|
22
|
+
number.gsub!(regexp_pattern(default_pattern),
|
23
|
+
"(\\1) \\2#{delimiter}\\3")
|
22
24
|
number
|
23
25
|
end
|
24
26
|
|
25
27
|
def convert_without_area_code(number)
|
26
|
-
|
28
|
+
default_pattern = /(\d{0,3})(\d{3})(\d{4})$/
|
29
|
+
number.gsub!(regexp_pattern(default_pattern),
|
30
|
+
"\\1#{delimiter}\\2#{delimiter}\\3")
|
27
31
|
number.slice!(0, 1) if start_with_delimiter?(number)
|
28
32
|
number
|
29
33
|
end
|
@@ -43,6 +47,11 @@ module ActiveSupport
|
|
43
47
|
def phone_ext(ext)
|
44
48
|
ext.blank? ? "" : " x #{ext}"
|
45
49
|
end
|
50
|
+
|
51
|
+
def regexp_pattern(default_pattern)
|
52
|
+
opts.fetch :pattern, default_pattern
|
53
|
+
end
|
54
|
+
|
46
55
|
end
|
47
56
|
end
|
48
57
|
end
|
@@ -6,36 +6,41 @@ module ActiveSupport
|
|
6
6
|
|
7
7
|
def convert
|
8
8
|
precision = options.delete :precision
|
9
|
-
significant = options.delete :significant
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if significant && precision > 0
|
21
|
-
digits, rounded_number = digits_and_rounded_number(precision)
|
22
|
-
precision -= digits
|
23
|
-
precision = 0 if precision < 0 # don't let it be negative
|
24
|
-
else
|
25
|
-
rounded_number = number.round(precision)
|
26
|
-
rounded_number = rounded_number.to_i if precision == 0
|
27
|
-
rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
|
28
|
-
end
|
10
|
+
if precision
|
11
|
+
case number
|
12
|
+
when Float, String
|
13
|
+
@number = BigDecimal(number.to_s)
|
14
|
+
when Rational
|
15
|
+
@number = BigDecimal(number, digit_count(number.to_i) + precision)
|
16
|
+
else
|
17
|
+
@number = number.to_d
|
18
|
+
end
|
29
19
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
a + '.' + b[0, precision]
|
20
|
+
if options.delete(:significant) && precision > 0
|
21
|
+
digits, rounded_number = digits_and_rounded_number(precision)
|
22
|
+
precision -= digits
|
23
|
+
precision = 0 if precision < 0 # don't let it be negative
|
35
24
|
else
|
36
|
-
|
25
|
+
rounded_number = number.round(precision)
|
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
|
37
28
|
end
|
38
29
|
|
30
|
+
formatted_string =
|
31
|
+
if BigDecimal === rounded_number && rounded_number.finite?
|
32
|
+
s = rounded_number.to_s('F')
|
33
|
+
s << '0'.freeze * precision
|
34
|
+
a, b = s.split('.'.freeze, 2)
|
35
|
+
a << '.'.freeze
|
36
|
+
a << b[0, precision]
|
37
|
+
else
|
38
|
+
"%00.#{precision}f" % rounded_number
|
39
|
+
end
|
40
|
+
else
|
41
|
+
formatted_string = number
|
42
|
+
end
|
43
|
+
|
39
44
|
delimited_number = NumberToDelimitedConverter.convert(formatted_string, options)
|
40
45
|
format_number(delimited_number)
|
41
46
|
end
|