activesupport 4.2.11.1 → 5.2.8.1
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 +441 -399
- 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 +91 -91
- 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 +466 -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 +35 -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 +62 -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 +314 -38
- 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 +131 -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 +5 -3
- 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 +57 -27
- 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/json"
|
4
|
+
require "active_support/core_ext/string/access"
|
5
|
+
require "active_support/core_ext/string/behavior"
|
6
|
+
require "active_support/core_ext/module/delegation"
|
7
|
+
require "active_support/core_ext/regexp"
|
6
8
|
|
7
9
|
module ActiveSupport #:nodoc:
|
8
10
|
module Multibyte #:nodoc:
|
@@ -16,7 +18,8 @@ module ActiveSupport #:nodoc:
|
|
16
18
|
# through the +mb_chars+ method. Methods which would normally return a
|
17
19
|
# String object now return a Chars object so methods can be chained.
|
18
20
|
#
|
19
|
-
# 'The Perfect String '.mb_chars.downcase.strip.normalize
|
21
|
+
# 'The Perfect String '.mb_chars.downcase.strip.normalize
|
22
|
+
# # => #<ActiveSupport::Multibyte::Chars:0x007fdc434ccc10 @wrapped_string="the perfect string">
|
20
23
|
#
|
21
24
|
# Chars objects are perfectly interchangeable with String objects as long as
|
22
25
|
# no explicit class checks are made. If certain methods do explicitly check
|
@@ -46,7 +49,7 @@ module ActiveSupport #:nodoc:
|
|
46
49
|
alias to_s wrapped_string
|
47
50
|
alias to_str wrapped_string
|
48
51
|
|
49
|
-
delegate :<=>, :=~, :acts_like_string?, :
|
52
|
+
delegate :<=>, :=~, :acts_like_string?, to: :wrapped_string
|
50
53
|
|
51
54
|
# Creates a new Chars instance by wrapping _string_.
|
52
55
|
def initialize(string)
|
@@ -57,7 +60,7 @@ module ActiveSupport #:nodoc:
|
|
57
60
|
# Forward all undefined methods to the wrapped string.
|
58
61
|
def method_missing(method, *args, &block)
|
59
62
|
result = @wrapped_string.__send__(method, *args, &block)
|
60
|
-
if method
|
63
|
+
if /!$/.match?(method)
|
61
64
|
self if result
|
62
65
|
else
|
63
66
|
result.kind_of?(String) ? chars(result) : result
|
@@ -87,16 +90,26 @@ module ActiveSupport #:nodoc:
|
|
87
90
|
end
|
88
91
|
|
89
92
|
# Works like <tt>String#slice!</tt>, but returns an instance of
|
90
|
-
# Chars, or nil if the string was not modified.
|
93
|
+
# Chars, or +nil+ if the string was not modified. The string will not be
|
94
|
+
# modified if the range given is out of bounds
|
95
|
+
#
|
96
|
+
# string = 'Welcome'
|
97
|
+
# string.mb_chars.slice!(3) # => #<ActiveSupport::Multibyte::Chars:0x000000038109b8 @wrapped_string="c">
|
98
|
+
# string # => 'Welome'
|
99
|
+
# string.mb_chars.slice!(0..3) # => #<ActiveSupport::Multibyte::Chars:0x00000002eb80a0 @wrapped_string="Welo">
|
100
|
+
# string # => 'me'
|
91
101
|
def slice!(*args)
|
92
|
-
|
102
|
+
string_sliced = @wrapped_string.slice!(*args)
|
103
|
+
if string_sliced
|
104
|
+
chars(string_sliced)
|
105
|
+
end
|
93
106
|
end
|
94
107
|
|
95
108
|
# Reverses all characters in the string.
|
96
109
|
#
|
97
110
|
# 'Café'.mb_chars.reverse.to_s # => 'éfaC'
|
98
111
|
def reverse
|
99
|
-
chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack(
|
112
|
+
chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack("U*"))
|
100
113
|
end
|
101
114
|
|
102
115
|
# Limits the byte size of the string to a number of bytes without breaking
|
@@ -124,7 +137,7 @@ module ActiveSupport #:nodoc:
|
|
124
137
|
|
125
138
|
# Converts characters in the string to the opposite case.
|
126
139
|
#
|
127
|
-
# 'El Cañón
|
140
|
+
# 'El Cañón'.mb_chars.swapcase.to_s # => "eL cAÑÓN"
|
128
141
|
def swapcase
|
129
142
|
chars Unicode.swapcase(@wrapped_string)
|
130
143
|
end
|
@@ -133,15 +146,15 @@ module ActiveSupport #:nodoc:
|
|
133
146
|
#
|
134
147
|
# 'über'.mb_chars.capitalize.to_s # => "Über"
|
135
148
|
def capitalize
|
136
|
-
(slice(0) || chars(
|
149
|
+
(slice(0) || chars("")).upcase + (slice(1..-1) || chars("")).downcase
|
137
150
|
end
|
138
151
|
|
139
152
|
# Capitalizes the first letter of every word, when possible.
|
140
153
|
#
|
141
|
-
# "ÉL QUE SE ENTERÓ".mb_chars.titleize # => "Él Que Se Enteró"
|
142
|
-
# "日本語".mb_chars.titleize
|
154
|
+
# "ÉL QUE SE ENTERÓ".mb_chars.titleize.to_s # => "Él Que Se Enteró"
|
155
|
+
# "日本語".mb_chars.titleize.to_s # => "日本語"
|
143
156
|
def titleize
|
144
|
-
chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1)})
|
157
|
+
chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1) })
|
145
158
|
end
|
146
159
|
alias_method :titlecase, :titleize
|
147
160
|
|
@@ -161,7 +174,7 @@ module ActiveSupport #:nodoc:
|
|
161
174
|
# 'é'.length # => 2
|
162
175
|
# 'é'.mb_chars.decompose.to_s.length # => 3
|
163
176
|
def decompose
|
164
|
-
chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack(
|
177
|
+
chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack("U*"))
|
165
178
|
end
|
166
179
|
|
167
180
|
# Performs composition on all the characters.
|
@@ -169,7 +182,7 @@ module ActiveSupport #:nodoc:
|
|
169
182
|
# 'é'.length # => 3
|
170
183
|
# 'é'.mb_chars.compose.to_s.length # => 2
|
171
184
|
def compose
|
172
|
-
chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack(
|
185
|
+
chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack("U*"))
|
173
186
|
end
|
174
187
|
|
175
188
|
# Returns the number of grapheme clusters in the string.
|
@@ -200,21 +213,21 @@ module ActiveSupport #:nodoc:
|
|
200
213
|
end
|
201
214
|
end
|
202
215
|
|
203
|
-
|
216
|
+
private
|
204
217
|
|
205
|
-
def translate_offset(byte_offset)
|
218
|
+
def translate_offset(byte_offset)
|
206
219
|
return nil if byte_offset.nil?
|
207
|
-
return 0 if @wrapped_string ==
|
220
|
+
return 0 if @wrapped_string == ""
|
208
221
|
|
209
222
|
begin
|
210
|
-
@wrapped_string.byteslice(0...byte_offset).unpack(
|
223
|
+
@wrapped_string.byteslice(0...byte_offset).unpack("U*").length
|
211
224
|
rescue ArgumentError
|
212
225
|
byte_offset -= 1
|
213
226
|
retry
|
214
227
|
end
|
215
228
|
end
|
216
229
|
|
217
|
-
def chars(string)
|
230
|
+
def chars(string)
|
218
231
|
self.class.new(string)
|
219
232
|
end
|
220
233
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActiveSupport
|
3
4
|
module Multibyte
|
4
5
|
module Unicode
|
5
|
-
|
6
6
|
extend self
|
7
7
|
|
8
8
|
# A list of all available normalization forms.
|
@@ -11,7 +11,7 @@ module ActiveSupport
|
|
11
11
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
12
12
|
|
13
13
|
# The Unicode version that is supported by the implementation
|
14
|
-
UNICODE_VERSION =
|
14
|
+
UNICODE_VERSION = "9.0.0"
|
15
15
|
|
16
16
|
# The default normalization used for operations that require
|
17
17
|
# normalization. It can be set to any of the normalizations
|
@@ -32,36 +32,6 @@ module ActiveSupport
|
|
32
32
|
HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
|
33
33
|
HANGUL_SCOUNT = 11172
|
34
34
|
HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
|
35
|
-
HANGUL_JAMO_FIRST = 0x1100
|
36
|
-
HANGUL_JAMO_LAST = 0x11FF
|
37
|
-
|
38
|
-
# All the unicode whitespace
|
39
|
-
WHITESPACE = [
|
40
|
-
(0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D>
|
41
|
-
0x0020, # White_Space # Zs SPACE
|
42
|
-
0x0085, # White_Space # Cc <control-0085>
|
43
|
-
0x00A0, # White_Space # Zs NO-BREAK SPACE
|
44
|
-
0x1680, # White_Space # Zs OGHAM SPACE MARK
|
45
|
-
(0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE
|
46
|
-
0x2028, # White_Space # Zl LINE SEPARATOR
|
47
|
-
0x2029, # White_Space # Zp PARAGRAPH SEPARATOR
|
48
|
-
0x202F, # White_Space # Zs NARROW NO-BREAK SPACE
|
49
|
-
0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE
|
50
|
-
0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
|
51
|
-
].flatten.freeze
|
52
|
-
|
53
|
-
# BOM (byte order mark) can also be seen as whitespace, it's a
|
54
|
-
# non-rendering character used to distinguish between little and big
|
55
|
-
# endian. This is not an issue in utf-8, so it must be ignored.
|
56
|
-
LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
|
57
|
-
|
58
|
-
# Returns a regular expression pattern that matches the passed Unicode
|
59
|
-
# codepoints.
|
60
|
-
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
|
61
|
-
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
|
62
|
-
end
|
63
|
-
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
|
64
|
-
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
|
65
35
|
|
66
36
|
# Detect whether the codepoint is in a certain character class. Returns
|
67
37
|
# +true+ when it's in the specified character class and +false+ otherwise.
|
@@ -84,24 +54,59 @@ module ActiveSupport
|
|
84
54
|
pos = 0
|
85
55
|
marker = 0
|
86
56
|
eoc = codepoints.length
|
87
|
-
while(pos < eoc)
|
57
|
+
while (pos < eoc)
|
88
58
|
pos += 1
|
89
|
-
previous = codepoints[pos-1]
|
59
|
+
previous = codepoints[pos - 1]
|
90
60
|
current = codepoints[pos]
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
)
|
103
|
-
|
104
|
-
|
61
|
+
|
62
|
+
# See http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
|
63
|
+
should_break =
|
64
|
+
if pos == eoc
|
65
|
+
true
|
66
|
+
# GB3. CR X LF
|
67
|
+
elsif previous == database.boundary[:cr] && current == database.boundary[:lf]
|
68
|
+
false
|
69
|
+
# GB4. (Control|CR|LF) ÷
|
70
|
+
elsif previous && in_char_class?(previous, [:control, :cr, :lf])
|
71
|
+
true
|
72
|
+
# GB5. ÷ (Control|CR|LF)
|
73
|
+
elsif in_char_class?(current, [:control, :cr, :lf])
|
74
|
+
true
|
75
|
+
# GB6. L X (L|V|LV|LVT)
|
76
|
+
elsif database.boundary[:l] === previous && in_char_class?(current, [:l, :v, :lv, :lvt])
|
77
|
+
false
|
78
|
+
# GB7. (LV|V) X (V|T)
|
79
|
+
elsif in_char_class?(previous, [:lv, :v]) && in_char_class?(current, [:v, :t])
|
80
|
+
false
|
81
|
+
# GB8. (LVT|T) X (T)
|
82
|
+
elsif in_char_class?(previous, [:lvt, :t]) && database.boundary[:t] === current
|
83
|
+
false
|
84
|
+
# GB9. X (Extend | ZWJ)
|
85
|
+
elsif in_char_class?(current, [:extend, :zwj])
|
86
|
+
false
|
87
|
+
# GB9a. X SpacingMark
|
88
|
+
elsif database.boundary[:spacingmark] === current
|
89
|
+
false
|
90
|
+
# GB9b. Prepend X
|
91
|
+
elsif database.boundary[:prepend] === previous
|
92
|
+
false
|
93
|
+
# GB10. (E_Base | EBG) Extend* X E_Modifier
|
94
|
+
elsif (marker...pos).any? { |i| in_char_class?(codepoints[i], [:e_base, :e_base_gaz]) && codepoints[i + 1...pos].all? { |c| database.boundary[:extend] === c } } && database.boundary[:e_modifier] === current
|
95
|
+
false
|
96
|
+
# GB11. ZWJ X (Glue_After_Zwj | EBG)
|
97
|
+
elsif database.boundary[:zwj] === previous && in_char_class?(current, [:glue_after_zwj, :e_base_gaz])
|
98
|
+
false
|
99
|
+
# GB12. ^ (RI RI)* RI X RI
|
100
|
+
# GB13. [^RI] (RI RI)* RI X RI
|
101
|
+
elsif codepoints[marker..pos].all? { |c| database.boundary[:regional_indicator] === c } && codepoints[marker..pos].count { |c| database.boundary[:regional_indicator] === c }.even?
|
102
|
+
false
|
103
|
+
# GB999. Any ÷ Any
|
104
|
+
else
|
105
|
+
true
|
106
|
+
end
|
107
|
+
|
108
|
+
if should_break
|
109
|
+
unpacked << codepoints[marker..pos - 1]
|
105
110
|
marker = pos
|
106
111
|
end
|
107
112
|
end
|
@@ -112,17 +117,17 @@ module ActiveSupport
|
|
112
117
|
#
|
113
118
|
# Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
|
114
119
|
def pack_graphemes(unpacked)
|
115
|
-
unpacked.flatten.pack(
|
120
|
+
unpacked.flatten.pack("U*")
|
116
121
|
end
|
117
122
|
|
118
123
|
# Re-order codepoints so the string becomes canonical.
|
119
124
|
def reorder_characters(codepoints)
|
120
|
-
length = codepoints.length- 1
|
125
|
+
length = codepoints.length - 1
|
121
126
|
pos = 0
|
122
127
|
while pos < length do
|
123
|
-
cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
|
128
|
+
cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos + 1]]
|
124
129
|
if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
|
125
|
-
codepoints[pos..pos+1] = cp2.code, cp1.code
|
130
|
+
codepoints[pos..pos + 1] = cp2.code, cp1.code
|
126
131
|
pos += (pos > 0 ? -1 : 1)
|
127
132
|
else
|
128
133
|
pos += 1
|
@@ -135,7 +140,7 @@ module ActiveSupport
|
|
135
140
|
def decompose(type, codepoints)
|
136
141
|
codepoints.inject([]) do |decomposed, cp|
|
137
142
|
# if it's a hangul syllable starter character
|
138
|
-
if HANGUL_SBASE <= cp
|
143
|
+
if HANGUL_SBASE <= cp && cp < HANGUL_SLAST
|
139
144
|
sindex = cp - HANGUL_SBASE
|
140
145
|
ncp = [] # new codepoints
|
141
146
|
ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
|
@@ -144,7 +149,7 @@ module ActiveSupport
|
|
144
149
|
ncp << (HANGUL_TBASE + tindex) unless tindex == 0
|
145
150
|
decomposed.concat ncp
|
146
151
|
# if the codepoint is decomposable in with the current decomposition type
|
147
|
-
elsif (ncp = database.codepoints[cp].decomp_mapping)
|
152
|
+
elsif (ncp = database.codepoints[cp].decomp_mapping) && (!database.codepoints[cp].decomp_type || type == :compatibility)
|
148
153
|
decomposed.concat decompose(type, ncp.dup)
|
149
154
|
else
|
150
155
|
decomposed << cp
|
@@ -163,11 +168,11 @@ module ActiveSupport
|
|
163
168
|
pos += 1
|
164
169
|
lindex = starter_char - HANGUL_LBASE
|
165
170
|
# -- Hangul
|
166
|
-
if 0 <= lindex
|
167
|
-
vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
|
168
|
-
if 0 <= vindex
|
169
|
-
tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
|
170
|
-
if 0 <= tindex
|
171
|
+
if 0 <= lindex && lindex < HANGUL_LCOUNT
|
172
|
+
vindex = codepoints[starter_pos + 1] - HANGUL_VBASE rescue vindex = -1
|
173
|
+
if 0 <= vindex && vindex < HANGUL_VCOUNT
|
174
|
+
tindex = codepoints[starter_pos + 2] - HANGUL_TBASE rescue tindex = -1
|
175
|
+
if 0 <= tindex && tindex < HANGUL_TCOUNT
|
171
176
|
j = starter_pos + 2
|
172
177
|
eoa -= 2
|
173
178
|
else
|
@@ -211,9 +216,8 @@ module ActiveSupport
|
|
211
216
|
codepoints
|
212
217
|
end
|
213
218
|
|
214
|
-
# Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
|
215
219
|
# Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
|
216
|
-
if
|
220
|
+
if !defined?(Rubinius)
|
217
221
|
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
218
222
|
# resulting in a valid UTF-8 string.
|
219
223
|
#
|
@@ -236,7 +240,7 @@ module ActiveSupport
|
|
236
240
|
reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
|
237
241
|
|
238
242
|
source = string.dup
|
239
|
-
out =
|
243
|
+
out = "".force_encoding(Encoding::UTF_16LE)
|
240
244
|
|
241
245
|
loop do
|
242
246
|
reader.primitive_convert(source, out)
|
@@ -258,23 +262,23 @@ module ActiveSupport
|
|
258
262
|
# * <tt>string</tt> - The string to perform normalization on.
|
259
263
|
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
260
264
|
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
261
|
-
# Default is ActiveSupport::Multibyte.default_normalization_form.
|
262
|
-
def normalize(string, form=nil)
|
265
|
+
# Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
|
266
|
+
def normalize(string, form = nil)
|
263
267
|
form ||= @default_normalization_form
|
264
268
|
# See http://www.unicode.org/reports/tr15, Table 1
|
265
269
|
codepoints = string.codepoints.to_a
|
266
270
|
case form
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
end.pack(
|
271
|
+
when :d
|
272
|
+
reorder_characters(decompose(:canonical, codepoints))
|
273
|
+
when :c
|
274
|
+
compose(reorder_characters(decompose(:canonical, codepoints)))
|
275
|
+
when :kd
|
276
|
+
reorder_characters(decompose(:compatibility, codepoints))
|
277
|
+
when :kc
|
278
|
+
compose(reorder_characters(decompose(:compatibility, codepoints)))
|
279
|
+
else
|
280
|
+
raise ArgumentError, "#{form} is not a valid normalization variant", caller
|
281
|
+
end.pack("U*".freeze)
|
278
282
|
end
|
279
283
|
|
280
284
|
def downcase(string)
|
@@ -333,13 +337,13 @@ module ActiveSupport
|
|
333
337
|
# UnicodeDatabase.
|
334
338
|
def load
|
335
339
|
begin
|
336
|
-
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename,
|
340
|
+
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, "rb") { |f| Marshal.load f.read }
|
337
341
|
rescue => e
|
338
342
|
raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
|
339
343
|
end
|
340
344
|
|
341
345
|
# Redefine the === method so we can write shorter rules for grapheme cluster breaks
|
342
|
-
@boundary.
|
346
|
+
@boundary.each_key do |k|
|
343
347
|
@boundary[k].instance_eval do
|
344
348
|
def ===(other)
|
345
349
|
detect { |i| i === other } ? true : false
|
@@ -355,7 +359,7 @@ module ActiveSupport
|
|
355
359
|
|
356
360
|
# Returns the directory in which the data files are stored.
|
357
361
|
def self.dirname
|
358
|
-
File.
|
362
|
+
File.expand_path("../values", __dir__)
|
359
363
|
end
|
360
364
|
|
361
365
|
# Returns the filename for the data file for this version.
|
@@ -366,25 +370,25 @@ module ActiveSupport
|
|
366
370
|
|
367
371
|
private
|
368
372
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
373
|
+
def apply_mapping(string, mapping)
|
374
|
+
database.codepoints
|
375
|
+
string.each_codepoint.map do |codepoint|
|
376
|
+
cp = database.codepoints[codepoint]
|
377
|
+
if cp && (ncp = cp.send(mapping)) && ncp > 0
|
378
|
+
ncp
|
379
|
+
else
|
380
|
+
codepoint
|
381
|
+
end
|
382
|
+
end.pack("U*")
|
383
|
+
end
|
380
384
|
|
381
|
-
|
382
|
-
|
383
|
-
|
385
|
+
def recode_windows1252_chars(string)
|
386
|
+
string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
|
387
|
+
end
|
384
388
|
|
385
|
-
|
386
|
-
|
387
|
-
|
389
|
+
def database
|
390
|
+
@database ||= UnicodeDatabase.new
|
391
|
+
end
|
388
392
|
end
|
389
393
|
end
|
390
394
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport #:nodoc:
|
2
4
|
module Multibyte
|
3
|
-
autoload :Chars,
|
4
|
-
autoload :Unicode,
|
5
|
+
autoload :Chars, "active_support/multibyte/chars"
|
6
|
+
autoload :Unicode, "active_support/multibyte/unicode"
|
5
7
|
|
6
8
|
# The proxy class returned when calling mb_chars. You can use this accessor
|
7
9
|
# to configure your own proxy class so you can support other encodings. See
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mutex_m"
|
4
|
+
require "concurrent/map"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
module Notifications
|
@@ -12,12 +14,12 @@ module ActiveSupport
|
|
12
14
|
|
13
15
|
def initialize
|
14
16
|
@subscribers = []
|
15
|
-
@listeners_for =
|
17
|
+
@listeners_for = Concurrent::Map.new
|
16
18
|
super
|
17
19
|
end
|
18
20
|
|
19
|
-
def subscribe(pattern = nil,
|
20
|
-
subscriber = Subscribers.new
|
21
|
+
def subscribe(pattern = nil, callable = nil, &block)
|
22
|
+
subscriber = Subscribers.new(pattern, callable || block)
|
21
23
|
synchronize do
|
22
24
|
@subscribers << subscriber
|
23
25
|
@listeners_for.clear
|
@@ -42,8 +44,8 @@ module ActiveSupport
|
|
42
44
|
listeners_for(name).each { |s| s.start(name, id, payload) }
|
43
45
|
end
|
44
46
|
|
45
|
-
def finish(name, id, payload)
|
46
|
-
|
47
|
+
def finish(name, id, payload, listeners = listeners_for(name))
|
48
|
+
listeners.each { |s| s.finish(name, id, payload) }
|
47
49
|
end
|
48
50
|
|
49
51
|
def publish(name, *args)
|
@@ -51,7 +53,7 @@ module ActiveSupport
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def listeners_for(name)
|
54
|
-
# this is correctly done double-checked locking (
|
56
|
+
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
|
55
57
|
@listeners_for[name] || synchronize do
|
56
58
|
# use synchronisation when accessing @subscribers
|
57
59
|
@listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
|
@@ -68,7 +70,7 @@ module ActiveSupport
|
|
68
70
|
|
69
71
|
module Subscribers # :nodoc:
|
70
72
|
def self.new(pattern, listener)
|
71
|
-
if listener.respond_to?(:start)
|
73
|
+
if listener.respond_to?(:start) && listener.respond_to?(:finish)
|
72
74
|
subscriber = Evented.new pattern, listener
|
73
75
|
else
|
74
76
|
subscriber = Timed.new pattern, listener
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
6
|
module Notifications
|
@@ -14,15 +16,17 @@ module ActiveSupport
|
|
14
16
|
# Instrument the given block by measuring the time taken to execute it
|
15
17
|
# and publish it. Notice that events get sent even if an error occurs
|
16
18
|
# in the passed-in block.
|
17
|
-
def instrument(name, payload={})
|
18
|
-
|
19
|
+
def instrument(name, payload = {})
|
20
|
+
# some of the listeners might have state
|
21
|
+
listeners_state = start name, payload
|
19
22
|
begin
|
20
23
|
yield payload
|
21
24
|
rescue Exception => e
|
22
25
|
payload[:exception] = [e.class.name, e.message]
|
26
|
+
payload[:exception_object] = e
|
23
27
|
raise e
|
24
28
|
ensure
|
25
|
-
|
29
|
+
finish_with_state listeners_state, name, payload
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -36,11 +40,15 @@ module ActiveSupport
|
|
36
40
|
@notifier.finish name, @id, payload
|
37
41
|
end
|
38
42
|
|
43
|
+
def finish_with_state(listeners_state, name, payload)
|
44
|
+
@notifier.finish name, @id, payload, listeners_state
|
45
|
+
end
|
46
|
+
|
39
47
|
private
|
40
48
|
|
41
|
-
|
42
|
-
|
43
|
-
|
49
|
+
def unique_id
|
50
|
+
SecureRandom.hex(10)
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
46
54
|
class Event
|
@@ -57,6 +65,18 @@ module ActiveSupport
|
|
57
65
|
@duration = nil
|
58
66
|
end
|
59
67
|
|
68
|
+
# Returns the difference in milliseconds between when the execution of the
|
69
|
+
# event started and when it ended.
|
70
|
+
#
|
71
|
+
# ActiveSupport::Notifications.subscribe('wait') do |*args|
|
72
|
+
# @event = ActiveSupport::Notifications::Event.new(*args)
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# ActiveSupport::Notifications.instrument('wait') do
|
76
|
+
# sleep 1
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @event.duration # => 1000.138
|
60
80
|
def duration
|
61
81
|
@duration ||= 1000.0 * (self.end - time)
|
62
82
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/notifications/instrumenter"
|
4
|
+
require "active_support/notifications/fanout"
|
5
|
+
require "active_support/per_thread_registry"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
# = Notifications
|
@@ -13,7 +15,7 @@ module ActiveSupport
|
|
13
15
|
# To instrument an event you just need to do:
|
14
16
|
#
|
15
17
|
# ActiveSupport::Notifications.instrument('render', extra: :information) do
|
16
|
-
# render
|
18
|
+
# render plain: 'Foo'
|
17
19
|
# end
|
18
20
|
#
|
19
21
|
# That first executes the block and then notifies all subscribers once done.
|
@@ -48,7 +50,7 @@ module ActiveSupport
|
|
48
50
|
# The block is saved and will be called whenever someone instruments "render":
|
49
51
|
#
|
50
52
|
# ActiveSupport::Notifications.instrument('render', extra: :information) do
|
51
|
-
# render
|
53
|
+
# render plain: 'Foo'
|
52
54
|
# end
|
53
55
|
#
|
54
56
|
# event = events.first
|
@@ -64,13 +66,15 @@ module ActiveSupport
|
|
64
66
|
# If an exception happens during that particular instrumentation the payload will
|
65
67
|
# have a key <tt>:exception</tt> with an array of two elements as value: a string with
|
66
68
|
# the name of the exception class, and the exception message.
|
69
|
+
# The <tt>:exception_object</tt> key of the payload will have the exception
|
70
|
+
# itself as the value.
|
67
71
|
#
|
68
72
|
# As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
|
69
73
|
# is able to take the arguments as they come and provide an object-oriented
|
70
74
|
# interface to that data.
|
71
75
|
#
|
72
|
-
# It is also possible to pass an object
|
73
|
-
# <tt>subscribe</tt> method instead of a block:
|
76
|
+
# It is also possible to pass an object which responds to <tt>call</tt> method
|
77
|
+
# as the second parameter to the <tt>subscribe</tt> method instead of a block:
|
74
78
|
#
|
75
79
|
# module ActionController
|
76
80
|
# class PageRequest
|