activesupport 5.2.4.4 → 6.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 +327 -408
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -2
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +28 -1
- data/lib/active_support/cache.rb +45 -23
- data/lib/active_support/cache/file_store.rb +22 -22
- data/lib/active_support/cache/mem_cache_store.rb +17 -2
- data/lib/active_support/cache/memory_store.rb +7 -2
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +47 -25
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +97 -73
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +33 -7
- data/lib/active_support/core_ext/module/introspection.rb +37 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/try.rb +15 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +22 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/include_range.rb +6 -0
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +61 -5
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +1 -0
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +69 -16
- data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +8 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
- data/lib/active_support/descendants_tracker.rb +56 -9
- data/lib/active_support/duration.rb +4 -3
- data/lib/active_support/duration/iso8601_parser.rb +2 -3
- data/lib/active_support/duration/iso8601_serializer.rb +3 -4
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +2 -1
- data/lib/active_support/evented_file_update_checker.rb +39 -9
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +22 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +9 -1
- data/lib/active_support/inflector/inflections.rb +1 -4
- data/lib/active_support/inflector/methods.rb +15 -27
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -23
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -1
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/log_subscriber.rb +31 -8
- data/lib/active_support/logger.rb +0 -15
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +26 -4
- data/lib/active_support/message_encryptor.rb +3 -5
- data/lib/active_support/message_verifier.rb +3 -3
- data/lib/active_support/multibyte/chars.rb +29 -48
- data/lib/active_support/multibyte/unicode.rb +44 -281
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +98 -13
- data/lib/active_support/notifications/instrumenter.rb +79 -8
- data/lib/active_support/number_helper.rb +7 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +129 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +65 -26
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +7 -7
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +12 -7
- data/lib/active_support/xml_mini.rb +2 -9
- data/lib/active_support/xml_mini/jdom.rb +2 -2
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- metadata +34 -9
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -34,7 +34,7 @@ module ActiveSupport
|
|
34
34
|
# name # => String, name of the event (such as 'render' from above)
|
35
35
|
# start # => Time, when the instrumented block started execution
|
36
36
|
# finish # => Time, when the instrumented block ended execution
|
37
|
-
# id # => String, unique ID for
|
37
|
+
# id # => String, unique ID for the instrumenter that fired the event
|
38
38
|
# payload # => Hash, the payload
|
39
39
|
# end
|
40
40
|
#
|
@@ -59,7 +59,7 @@ module ActiveSupport
|
|
59
59
|
# event.payload # => { extra: :information }
|
60
60
|
#
|
61
61
|
# The block in the <tt>subscribe</tt> call gets the name of the event, start
|
62
|
-
# timestamp, end timestamp, a string with a unique identifier for that event
|
62
|
+
# timestamp, end timestamp, a string with a unique identifier for that event's instrumenter
|
63
63
|
# (something like "535801666f04d0298cd6"), and a hash with the payload, in
|
64
64
|
# that order.
|
65
65
|
#
|
@@ -67,9 +67,12 @@ module ActiveSupport
|
|
67
67
|
# have a key <tt>:exception</tt> with an array of two elements as value: a string with
|
68
68
|
# the name of the exception class, and the exception message.
|
69
69
|
# The <tt>:exception_object</tt> key of the payload will have the exception
|
70
|
-
# itself as the value
|
70
|
+
# itself as the value:
|
71
71
|
#
|
72
|
-
#
|
72
|
+
# event.payload[:exception] # => ["ArgumentError", "Invalid value"]
|
73
|
+
# event.payload[:exception_object] # => #<ArgumentError: Invalid value>
|
74
|
+
#
|
75
|
+
# As the earlier example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
|
73
76
|
# is able to take the arguments as they come and provide an object-oriented
|
74
77
|
# interface to that data.
|
75
78
|
#
|
@@ -150,6 +153,15 @@ module ActiveSupport
|
|
150
153
|
#
|
151
154
|
# ActiveSupport::Notifications.unsubscribe("render")
|
152
155
|
#
|
156
|
+
# Subscribers using a regexp or other pattern-matching object will remain subscribed
|
157
|
+
# to all events that match their original pattern, unless those events match a string
|
158
|
+
# passed to `unsubscribe`:
|
159
|
+
#
|
160
|
+
# subscriber = ActiveSupport::Notifications.subscribe(/render/) { }
|
161
|
+
# ActiveSupport::Notifications.unsubscribe('render_template.action_view')
|
162
|
+
# subscriber.matches?('render_template.action_view') # => false
|
163
|
+
# subscriber.matches?('render_partial.action_view') # => true
|
164
|
+
#
|
153
165
|
# == Default Queue
|
154
166
|
#
|
155
167
|
# Notifications ships with a queue implementation that consumes and publishes events
|
@@ -171,6 +183,31 @@ module ActiveSupport
|
|
171
183
|
end
|
172
184
|
end
|
173
185
|
|
186
|
+
# Subscribe to a given event name with the passed +block+.
|
187
|
+
#
|
188
|
+
# You can subscribe to events by passing a String to match exact event
|
189
|
+
# names, or by passing a Regexp to match all events that match a pattern.
|
190
|
+
#
|
191
|
+
# ActiveSupport::Notifications.subscribe(/render/) do |*args|
|
192
|
+
# @event = ActiveSupport::Notifications::Event.new(*args)
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# The +block+ will receive five parameters with information about the event:
|
196
|
+
#
|
197
|
+
# ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
|
198
|
+
# name # => String, name of the event (such as 'render' from above)
|
199
|
+
# start # => Time, when the instrumented block started execution
|
200
|
+
# finish # => Time, when the instrumented block ended execution
|
201
|
+
# id # => String, unique ID for the instrumenter that fired the event
|
202
|
+
# payload # => Hash, the payload
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# If the block passed to the method only takes one parameter,
|
206
|
+
# it will yield an event object to the block:
|
207
|
+
#
|
208
|
+
# ActiveSupport::Notifications.subscribe(/render/) do |event|
|
209
|
+
# @event = event
|
210
|
+
# end
|
174
211
|
def subscribe(*args, &block)
|
175
212
|
notifier.subscribe(*args, &block)
|
176
213
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "mutex_m"
|
4
4
|
require "concurrent/map"
|
5
|
+
require "set"
|
5
6
|
|
6
7
|
module ActiveSupport
|
7
8
|
module Notifications
|
@@ -13,7 +14,8 @@ module ActiveSupport
|
|
13
14
|
include Mutex_m
|
14
15
|
|
15
16
|
def initialize
|
16
|
-
@
|
17
|
+
@string_subscribers = Hash.new { |h, k| h[k] = [] }
|
18
|
+
@other_subscribers = []
|
17
19
|
@listeners_for = Concurrent::Map.new
|
18
20
|
super
|
19
21
|
end
|
@@ -21,8 +23,13 @@ module ActiveSupport
|
|
21
23
|
def subscribe(pattern = nil, callable = nil, &block)
|
22
24
|
subscriber = Subscribers.new(pattern, callable || block)
|
23
25
|
synchronize do
|
24
|
-
|
25
|
-
|
26
|
+
if String === pattern
|
27
|
+
@string_subscribers[pattern] << subscriber
|
28
|
+
@listeners_for.delete(pattern)
|
29
|
+
else
|
30
|
+
@other_subscribers << subscriber
|
31
|
+
@listeners_for.clear
|
32
|
+
end
|
26
33
|
end
|
27
34
|
subscriber
|
28
35
|
end
|
@@ -31,12 +38,19 @@ module ActiveSupport
|
|
31
38
|
synchronize do
|
32
39
|
case subscriber_or_name
|
33
40
|
when String
|
34
|
-
@
|
41
|
+
@string_subscribers[subscriber_or_name].clear
|
42
|
+
@listeners_for.delete(subscriber_or_name)
|
43
|
+
@other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
|
35
44
|
else
|
36
|
-
|
45
|
+
pattern = subscriber_or_name.try(:pattern)
|
46
|
+
if String === pattern
|
47
|
+
@string_subscribers[pattern].delete(subscriber_or_name)
|
48
|
+
@listeners_for.delete(pattern)
|
49
|
+
else
|
50
|
+
@other_subscribers.delete(subscriber_or_name)
|
51
|
+
@listeners_for.clear
|
52
|
+
end
|
37
53
|
end
|
38
|
-
|
39
|
-
@listeners_for.clear
|
40
54
|
end
|
41
55
|
end
|
42
56
|
|
@@ -56,7 +70,8 @@ module ActiveSupport
|
|
56
70
|
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
|
57
71
|
@listeners_for[name] || synchronize do
|
58
72
|
# use synchronisation when accessing @subscribers
|
59
|
-
@listeners_for[name] ||=
|
73
|
+
@listeners_for[name] ||=
|
74
|
+
@string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
|
60
75
|
end
|
61
76
|
end
|
62
77
|
|
@@ -70,12 +85,29 @@ module ActiveSupport
|
|
70
85
|
|
71
86
|
module Subscribers # :nodoc:
|
72
87
|
def self.new(pattern, listener)
|
88
|
+
subscriber_class = Timed
|
89
|
+
|
73
90
|
if listener.respond_to?(:start) && listener.respond_to?(:finish)
|
74
|
-
|
91
|
+
subscriber_class = Evented
|
75
92
|
else
|
76
|
-
|
93
|
+
# Doing all this to detect a block like `proc { |x| }` vs
|
94
|
+
# `proc { |*x| }` or `proc { |**x| }`
|
95
|
+
if listener.respond_to?(:parameters)
|
96
|
+
params = listener.parameters
|
97
|
+
if params.length == 1 && params.first.first == :opt
|
98
|
+
subscriber_class = EventObject
|
99
|
+
end
|
100
|
+
end
|
77
101
|
end
|
78
102
|
|
103
|
+
wrap_all pattern, subscriber_class.new(pattern, listener)
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.event_object_subscriber(pattern, block)
|
107
|
+
wrap_all pattern, EventObject.new(pattern, block)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.wrap_all(pattern, subscriber)
|
79
111
|
unless pattern
|
80
112
|
AllMessages.new(subscriber)
|
81
113
|
else
|
@@ -83,9 +115,33 @@ module ActiveSupport
|
|
83
115
|
end
|
84
116
|
end
|
85
117
|
|
118
|
+
class Matcher #:nodoc:
|
119
|
+
attr_reader :pattern, :exclusions
|
120
|
+
|
121
|
+
def self.wrap(pattern)
|
122
|
+
return pattern if String === pattern
|
123
|
+
new(pattern)
|
124
|
+
end
|
125
|
+
|
126
|
+
def initialize(pattern)
|
127
|
+
@pattern = pattern
|
128
|
+
@exclusions = Set.new
|
129
|
+
end
|
130
|
+
|
131
|
+
def unsubscribe!(name)
|
132
|
+
exclusions << -name if pattern === name
|
133
|
+
end
|
134
|
+
|
135
|
+
def ===(name)
|
136
|
+
pattern === name && !exclusions.include?(name)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
86
140
|
class Evented #:nodoc:
|
141
|
+
attr_reader :pattern
|
142
|
+
|
87
143
|
def initialize(pattern, delegate)
|
88
|
-
@pattern = pattern
|
144
|
+
@pattern = Matcher.wrap(pattern)
|
89
145
|
@delegate = delegate
|
90
146
|
@can_publish = delegate.respond_to?(:publish)
|
91
147
|
end
|
@@ -105,11 +161,15 @@ module ActiveSupport
|
|
105
161
|
end
|
106
162
|
|
107
163
|
def subscribed_to?(name)
|
108
|
-
|
164
|
+
pattern === name
|
109
165
|
end
|
110
166
|
|
111
167
|
def matches?(name)
|
112
|
-
|
168
|
+
pattern && pattern === name
|
169
|
+
end
|
170
|
+
|
171
|
+
def unsubscribe!(name)
|
172
|
+
pattern.unsubscribe!(name)
|
113
173
|
end
|
114
174
|
end
|
115
175
|
|
@@ -130,6 +190,27 @@ module ActiveSupport
|
|
130
190
|
end
|
131
191
|
end
|
132
192
|
|
193
|
+
class EventObject < Evented
|
194
|
+
def start(name, id, payload)
|
195
|
+
stack = Thread.current[:_event_stack] ||= []
|
196
|
+
event = build_event name, id, payload
|
197
|
+
event.start!
|
198
|
+
stack.push event
|
199
|
+
end
|
200
|
+
|
201
|
+
def finish(name, id, payload)
|
202
|
+
stack = Thread.current[:_event_stack]
|
203
|
+
event = stack.pop
|
204
|
+
event.finish!
|
205
|
+
@delegate.call event
|
206
|
+
end
|
207
|
+
|
208
|
+
private
|
209
|
+
def build_event(name, id, payload)
|
210
|
+
ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
133
214
|
class AllMessages # :nodoc:
|
134
215
|
def initialize(delegate)
|
135
216
|
@delegate = delegate
|
@@ -151,6 +232,10 @@ module ActiveSupport
|
|
151
232
|
true
|
152
233
|
end
|
153
234
|
|
235
|
+
def unsubscribe!(*)
|
236
|
+
false
|
237
|
+
end
|
238
|
+
|
154
239
|
alias :matches? :===
|
155
240
|
end
|
156
241
|
end
|
@@ -13,14 +13,15 @@ module ActiveSupport
|
|
13
13
|
@notifier = notifier
|
14
14
|
end
|
15
15
|
|
16
|
-
#
|
17
|
-
# and publish it.
|
18
|
-
#
|
16
|
+
# Given a block, instrument it by measuring the time taken to execute
|
17
|
+
# and publish it. Without a block, simply send a message via the
|
18
|
+
# notifier. Notice that events get sent even if an error occurs in the
|
19
|
+
# passed-in block.
|
19
20
|
def instrument(name, payload = {})
|
20
21
|
# some of the listeners might have state
|
21
22
|
listeners_state = start name, payload
|
22
23
|
begin
|
23
|
-
yield payload
|
24
|
+
yield payload if block_given?
|
24
25
|
rescue Exception => e
|
25
26
|
payload[:exception] = [e.class.name, e.message]
|
26
27
|
payload[:exception_object] = e
|
@@ -52,8 +53,13 @@ module ActiveSupport
|
|
52
53
|
end
|
53
54
|
|
54
55
|
class Event
|
55
|
-
attr_reader :name, :time, :transaction_id, :payload, :children
|
56
|
-
|
56
|
+
attr_reader :name, :time, :end, :transaction_id, :payload, :children
|
57
|
+
|
58
|
+
def self.clock_gettime_supported? # :nodoc:
|
59
|
+
defined?(Process::CLOCK_PROCESS_CPUTIME_ID) &&
|
60
|
+
!Gem.win_platform?
|
61
|
+
end
|
62
|
+
private_class_method :clock_gettime_supported?
|
57
63
|
|
58
64
|
def initialize(name, start, ending, transaction_id, payload)
|
59
65
|
@name = name
|
@@ -62,7 +68,47 @@ module ActiveSupport
|
|
62
68
|
@transaction_id = transaction_id
|
63
69
|
@end = ending
|
64
70
|
@children = []
|
65
|
-
@
|
71
|
+
@cpu_time_start = 0
|
72
|
+
@cpu_time_finish = 0
|
73
|
+
@allocation_count_start = 0
|
74
|
+
@allocation_count_finish = 0
|
75
|
+
end
|
76
|
+
|
77
|
+
# Record information at the time this event starts
|
78
|
+
def start!
|
79
|
+
@time = now
|
80
|
+
@cpu_time_start = now_cpu
|
81
|
+
@allocation_count_start = now_allocations
|
82
|
+
end
|
83
|
+
|
84
|
+
# Record information at the time this event finishes
|
85
|
+
def finish!
|
86
|
+
@cpu_time_finish = now_cpu
|
87
|
+
@end = now
|
88
|
+
@allocation_count_finish = now_allocations
|
89
|
+
end
|
90
|
+
|
91
|
+
def end=(ending)
|
92
|
+
ActiveSupport::Deprecation.deprecation_warning(:end=, :finish!)
|
93
|
+
@end = ending
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns the CPU time (in milliseconds) passed since the call to
|
97
|
+
# +start!+ and the call to +finish!+
|
98
|
+
def cpu_time
|
99
|
+
(@cpu_time_finish - @cpu_time_start) * 1000
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the idle time time (in milliseconds) passed since the call to
|
103
|
+
# +start!+ and the call to +finish!+
|
104
|
+
def idle_time
|
105
|
+
duration - cpu_time
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns the number of allocations made since the call to +start!+ and
|
109
|
+
# the call to +finish!+
|
110
|
+
def allocations
|
111
|
+
@allocation_count_finish - @allocation_count_start
|
66
112
|
end
|
67
113
|
|
68
114
|
# Returns the difference in milliseconds between when the execution of the
|
@@ -78,7 +124,7 @@ module ActiveSupport
|
|
78
124
|
#
|
79
125
|
# @event.duration # => 1000.138
|
80
126
|
def duration
|
81
|
-
|
127
|
+
1000.0 * (self.end - time)
|
82
128
|
end
|
83
129
|
|
84
130
|
def <<(event)
|
@@ -88,6 +134,31 @@ module ActiveSupport
|
|
88
134
|
def parent_of?(event)
|
89
135
|
@children.include? event
|
90
136
|
end
|
137
|
+
|
138
|
+
private
|
139
|
+
def now
|
140
|
+
Concurrent.monotonic_time
|
141
|
+
end
|
142
|
+
|
143
|
+
if clock_gettime_supported?
|
144
|
+
def now_cpu
|
145
|
+
Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
|
146
|
+
end
|
147
|
+
else
|
148
|
+
def now_cpu
|
149
|
+
0
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
if defined?(JRUBY_VERSION)
|
154
|
+
def now_allocations
|
155
|
+
0
|
156
|
+
end
|
157
|
+
else
|
158
|
+
def now_allocations
|
159
|
+
GC.stat :total_allocated_objects
|
160
|
+
end
|
161
|
+
end
|
91
162
|
end
|
92
163
|
end
|
93
164
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/dependencies/autoload"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
module NumberHelper
|
5
7
|
extend ActiveSupport::Autoload
|
@@ -85,6 +87,9 @@ module ActiveSupport
|
|
85
87
|
# number given by <tt>:format</tt>). Accepts the same fields
|
86
88
|
# than <tt>:format</tt>, except <tt>%n</tt> is here the
|
87
89
|
# absolute value of the number.
|
90
|
+
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
|
91
|
+
# insignificant zeros after the decimal separator (defaults to
|
92
|
+
# +false+).
|
88
93
|
#
|
89
94
|
# ==== Examples
|
90
95
|
#
|
@@ -100,6 +105,8 @@ module ActiveSupport
|
|
100
105
|
# # => "£1234567890,50"
|
101
106
|
# number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '', format: '%n %u')
|
102
107
|
# # => "1234567890,50 £"
|
108
|
+
# number_to_currency(1234567890.50, strip_insignificant_zeros: true)
|
109
|
+
# # => "$1,234,567,890.5"
|
103
110
|
def number_to_currency(number, options = {})
|
104
111
|
NumberToCurrencyConverter.convert(number, options)
|
105
112
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/
|
3
|
+
require "active_support/number_helper/number_converter"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module NumberHelper
|
@@ -17,7 +17,7 @@ module ActiveSupport
|
|
17
17
|
end
|
18
18
|
|
19
19
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
20
|
-
format.gsub("%n"
|
20
|
+
format.gsub("%n", rounded_number).gsub("%u", options[:unit])
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/number_helper/number_converter"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
module NumberHelper
|
5
7
|
class NumberToDelimitedConverter < NumberConverter #:nodoc:
|
@@ -14,7 +16,7 @@ module ActiveSupport
|
|
14
16
|
private
|
15
17
|
|
16
18
|
def parts
|
17
|
-
left, right = number.to_s.split("."
|
19
|
+
left, right = number.to_s.split(".")
|
18
20
|
left.gsub!(delimiter_pattern) do |digit_to_delimit|
|
19
21
|
"#{digit_to_delimit}#{options[:delimiter]}"
|
20
22
|
end
|