activesupport 5.1.1 → 6.1.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 +5 -5
- data/CHANGELOG.md +360 -442
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -4
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +6 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -3
- data/lib/active_support/benchmarkable.rb +3 -1
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +37 -36
- data/lib/active_support/cache/mem_cache_store.rb +65 -53
- data/lib/active_support/cache/memory_store.rb +61 -33
- data/lib/active_support/cache/null_store.rb +10 -3
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +68 -22
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +305 -127
- data/lib/active_support/callbacks.rb +106 -98
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -1
- data/lib/active_support/configurable.rb +12 -14
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +7 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +3 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +18 -40
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -5
- data/lib/active_support/core_ext/date/conversions.rb +12 -10
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +174 -71
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -5
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +3 -30
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/marshal.rb +4 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +103 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -1
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +13 -3
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +6 -101
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +22 -2
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +7 -2
- data/lib/active_support/core_ext/object/try.rb +19 -7
- data/lib/active_support/core_ext/object/with_options.rb +4 -2
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +3 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +3 -0
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +76 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +73 -18
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +4 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +11 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +208 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +135 -60
- data/lib/active_support/deprecation/behaviors.rb +43 -11
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +30 -15
- data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +9 -2
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +6 -6
- data/lib/active_support/duration/iso8601_serializer.rb +20 -14
- data/lib/active_support/duration.rb +179 -41
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +84 -117
- data/lib/active_support/execution_wrapper.rb +3 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +134 -37
- data/lib/active_support/i18n.rb +4 -1
- data/lib/active_support/i18n_railtie.rb +20 -11
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +19 -8
- data/lib/active_support/inflector/methods.rb +87 -77
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +13 -3
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -33
- data/lib/active_support/lazy_load_hooks.rb +33 -10
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +46 -13
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +54 -7
- data/lib/active_support/message_encryptor.rb +101 -33
- data/lib/active_support/message_verifier.rb +85 -14
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +12 -68
- data/lib/active_support/multibyte/unicode.rb +17 -327
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +118 -16
- data/lib/active_support/notifications/instrumenter.rb +73 -9
- data/lib/active_support/notifications.rb +74 -8
- data/lib/active_support/number_helper/number_converter.rb +7 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
- data/lib/active_support/number_helper/rounding_helper.rb +50 -0
- data/lib/active_support/number_helper.rb +41 -12
- data/lib/active_support/option_merger.rb +24 -3
- data/lib/active_support/ordered_hash.rb +3 -1
- data/lib/active_support/ordered_options.rb +17 -5
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +3 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +60 -9
- data/lib/active_support/reloader.rb +11 -10
- data/lib/active_support/rescuable.rb +7 -6
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +6 -3
- data/lib/active_support/subscriber.rb +74 -24
- data/lib/active_support/tagged_logging.rb +44 -8
- data/lib/active_support/test_case.rb +94 -2
- data/lib/active_support/testing/assertions.rb +58 -20
- data/lib/active_support/testing/autorun.rb +2 -4
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -1
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +8 -4
- data/lib/active_support/testing/method_call_assertions.rb +30 -1
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +3 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +78 -13
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +113 -41
- data/lib/active_support/values/time_zone.rb +55 -25
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +5 -4
- data/lib/active_support/xml_mini/libxml.rb +4 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
- data/lib/active_support/xml_mini/nokogiri.rb +4 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
- data/lib/active_support/xml_mini/rexml.rb +12 -3
- data/lib/active_support/xml_mini.rb +5 -11
- data/lib/active_support.rb +18 -13
- metadata +81 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,11 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/concern"
|
2
4
|
require "active_support/descendants_tracker"
|
3
5
|
require "active_support/core_ext/array/extract_options"
|
4
6
|
require "active_support/core_ext/class/attribute"
|
5
|
-
require "active_support/core_ext/kernel/reporting"
|
6
|
-
require "active_support/core_ext/kernel/singleton_class"
|
7
7
|
require "active_support/core_ext/string/filters"
|
8
|
-
require "active_support/deprecation"
|
9
8
|
require "thread"
|
10
9
|
|
11
10
|
module ActiveSupport
|
@@ -21,6 +20,9 @@ module ActiveSupport
|
|
21
20
|
# +ClassMethods.set_callback+), and run the installed callbacks at the
|
22
21
|
# appropriate times (via +run_callbacks+).
|
23
22
|
#
|
23
|
+
# By default callbacks are halted by throwing +:abort+.
|
24
|
+
# See +ClassMethods.define_callbacks+ for details.
|
25
|
+
#
|
24
26
|
# Three kinds of callbacks are supported: before callbacks, run before a
|
25
27
|
# certain event; after callbacks, run after the event; and around callbacks,
|
26
28
|
# blocks that surround the event, triggering it when they yield. Callback code
|
@@ -62,8 +64,7 @@ module ActiveSupport
|
|
62
64
|
|
63
65
|
included do
|
64
66
|
extend ActiveSupport::DescendantsTracker
|
65
|
-
class_attribute :__callbacks, instance_writer: false
|
66
|
-
self.__callbacks ||= {}
|
67
|
+
class_attribute :__callbacks, instance_writer: false, default: {}
|
67
68
|
end
|
68
69
|
|
69
70
|
CALLBACK_FILTER_TYPES = [:before, :after, :around]
|
@@ -99,32 +100,6 @@ module ActiveSupport
|
|
99
100
|
env = Filters::Environment.new(self, false, nil)
|
100
101
|
next_sequence = callbacks.compile
|
101
102
|
|
102
|
-
invoke_sequence = Proc.new do
|
103
|
-
skipped = nil
|
104
|
-
while true
|
105
|
-
current = next_sequence
|
106
|
-
current.invoke_before(env)
|
107
|
-
if current.final?
|
108
|
-
env.value = !env.halted && (!block_given? || yield)
|
109
|
-
elsif current.skip?(env)
|
110
|
-
(skipped ||= []) << current
|
111
|
-
next_sequence = next_sequence.nested
|
112
|
-
next
|
113
|
-
else
|
114
|
-
next_sequence = next_sequence.nested
|
115
|
-
begin
|
116
|
-
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
|
117
|
-
target.send(method, *arguments, &block)
|
118
|
-
ensure
|
119
|
-
next_sequence = current
|
120
|
-
end
|
121
|
-
end
|
122
|
-
current.invoke_after(env)
|
123
|
-
skipped.pop.invoke_after(env) while skipped && skipped.first
|
124
|
-
break env.value
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
103
|
# Common case: no 'around' callbacks defined
|
129
104
|
if next_sequence.final?
|
130
105
|
next_sequence.invoke_before(env)
|
@@ -132,17 +107,43 @@ module ActiveSupport
|
|
132
107
|
next_sequence.invoke_after(env)
|
133
108
|
env.value
|
134
109
|
else
|
110
|
+
invoke_sequence = Proc.new do
|
111
|
+
skipped = nil
|
112
|
+
|
113
|
+
while true
|
114
|
+
current = next_sequence
|
115
|
+
current.invoke_before(env)
|
116
|
+
if current.final?
|
117
|
+
env.value = !env.halted && (!block_given? || yield)
|
118
|
+
elsif current.skip?(env)
|
119
|
+
(skipped ||= []) << current
|
120
|
+
next_sequence = next_sequence.nested
|
121
|
+
next
|
122
|
+
else
|
123
|
+
next_sequence = next_sequence.nested
|
124
|
+
begin
|
125
|
+
target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
|
126
|
+
target.send(method, *arguments, &block)
|
127
|
+
ensure
|
128
|
+
next_sequence = current
|
129
|
+
end
|
130
|
+
end
|
131
|
+
current.invoke_after(env)
|
132
|
+
skipped.pop.invoke_after(env) while skipped&.first
|
133
|
+
break env.value
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
135
137
|
invoke_sequence.call
|
136
138
|
end
|
137
139
|
end
|
138
140
|
end
|
139
141
|
|
140
142
|
private
|
141
|
-
|
142
143
|
# A hook invoked every time a before callback is halted.
|
143
144
|
# This can be overridden in ActiveSupport::Callbacks implementors in order
|
144
145
|
# to provide better debugging/logging.
|
145
|
-
def halted_callback_hook(filter)
|
146
|
+
def halted_callback_hook(filter, name)
|
146
147
|
end
|
147
148
|
|
148
149
|
module Conditionals # :nodoc:
|
@@ -158,17 +159,17 @@ module ActiveSupport
|
|
158
159
|
Environment = Struct.new(:target, :halted, :value)
|
159
160
|
|
160
161
|
class Before
|
161
|
-
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
|
162
|
+
def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter, name)
|
162
163
|
halted_lambda = chain_config[:terminator]
|
163
164
|
|
164
165
|
if user_conditions.any?
|
165
|
-
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
166
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
166
167
|
else
|
167
|
-
halting(callback_sequence, user_callback, halted_lambda, filter)
|
168
|
+
halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
168
169
|
end
|
169
170
|
end
|
170
171
|
|
171
|
-
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
172
|
+
def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter, name)
|
172
173
|
callback_sequence.before do |env|
|
173
174
|
target = env.target
|
174
175
|
value = env.value
|
@@ -178,7 +179,7 @@ module ActiveSupport
|
|
178
179
|
result_lambda = -> { user_callback.call target, value }
|
179
180
|
env.halted = halted_lambda.call(target, result_lambda)
|
180
181
|
if env.halted
|
181
|
-
target.send :halted_callback_hook, filter
|
182
|
+
target.send :halted_callback_hook, filter, name
|
182
183
|
end
|
183
184
|
end
|
184
185
|
|
@@ -187,7 +188,7 @@ module ActiveSupport
|
|
187
188
|
end
|
188
189
|
private_class_method :halting_and_conditional
|
189
190
|
|
190
|
-
def self.halting(callback_sequence, user_callback, halted_lambda, filter)
|
191
|
+
def self.halting(callback_sequence, user_callback, halted_lambda, filter, name)
|
191
192
|
callback_sequence.before do |env|
|
192
193
|
target = env.target
|
193
194
|
value = env.value
|
@@ -196,9 +197,8 @@ module ActiveSupport
|
|
196
197
|
unless halted
|
197
198
|
result_lambda = -> { user_callback.call target, value }
|
198
199
|
env.halted = halted_lambda.call(target, result_lambda)
|
199
|
-
|
200
200
|
if env.halted
|
201
|
-
target.send :halted_callback_hook, filter
|
201
|
+
target.send :halted_callback_hook, filter, name
|
202
202
|
end
|
203
203
|
end
|
204
204
|
|
@@ -297,8 +297,8 @@ module ActiveSupport
|
|
297
297
|
@kind = kind
|
298
298
|
@filter = filter
|
299
299
|
@key = compute_identifier filter
|
300
|
-
@if =
|
301
|
-
@unless =
|
300
|
+
@if = check_conditionals(options[:if])
|
301
|
+
@unless = check_conditionals(options[:unless])
|
302
302
|
end
|
303
303
|
|
304
304
|
def filter; @key; end
|
@@ -322,7 +322,7 @@ module ActiveSupport
|
|
322
322
|
|
323
323
|
def duplicates?(other)
|
324
324
|
case @filter
|
325
|
-
when Symbol
|
325
|
+
when Symbol
|
326
326
|
matches?(other.kind, other.filter)
|
327
327
|
else
|
328
328
|
false
|
@@ -336,7 +336,7 @@ module ActiveSupport
|
|
336
336
|
|
337
337
|
case kind
|
338
338
|
when :before
|
339
|
-
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter)
|
339
|
+
Filters::Before.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config, @filter, name)
|
340
340
|
when :after
|
341
341
|
Filters::After.build(callback_sequence, user_callback.make_lambda, user_conditions, chain_config)
|
342
342
|
when :around
|
@@ -349,9 +349,27 @@ module ActiveSupport
|
|
349
349
|
end
|
350
350
|
|
351
351
|
private
|
352
|
+
EMPTY_ARRAY = [].freeze
|
353
|
+
private_constant :EMPTY_ARRAY
|
354
|
+
|
355
|
+
def check_conditionals(conditionals)
|
356
|
+
return EMPTY_ARRAY if conditionals.blank?
|
357
|
+
|
358
|
+
conditionals = Array(conditionals)
|
359
|
+
if conditionals.any? { |c| c.is_a?(String) }
|
360
|
+
raise ArgumentError, <<-MSG.squish
|
361
|
+
Passing string to be evaluated in :if and :unless conditional
|
362
|
+
options is not supported. Pass a symbol for an instance method,
|
363
|
+
or a lambda, proc or block, instead.
|
364
|
+
MSG
|
365
|
+
end
|
366
|
+
|
367
|
+
conditionals.freeze
|
368
|
+
end
|
369
|
+
|
352
370
|
def compute_identifier(filter)
|
353
371
|
case filter
|
354
|
-
when
|
372
|
+
when ::Proc
|
355
373
|
filter.object_id
|
356
374
|
else
|
357
375
|
filter
|
@@ -388,21 +406,17 @@ module ActiveSupport
|
|
388
406
|
# The actual invocation is left up to the caller to minimize
|
389
407
|
# call stack pollution.
|
390
408
|
def expand(target, value, block)
|
391
|
-
|
409
|
+
expanded = [@override_target || target, @override_block || block, @method_name]
|
410
|
+
|
411
|
+
@arguments.each do |arg|
|
392
412
|
case arg
|
393
|
-
when :value
|
394
|
-
when :target
|
395
|
-
when :block
|
413
|
+
when :value then expanded << value
|
414
|
+
when :target then expanded << target
|
415
|
+
when :block then expanded << (block || raise(ArgumentError))
|
396
416
|
end
|
397
|
-
|
398
|
-
|
399
|
-
result.unshift @method_name
|
400
|
-
result.unshift @override_block || block
|
401
|
-
result.unshift @override_target || target
|
417
|
+
end
|
402
418
|
|
403
|
-
|
404
|
-
# target.send(method, *arguments, &block)
|
405
|
-
result
|
419
|
+
expanded
|
406
420
|
end
|
407
421
|
|
408
422
|
# Return a lambda that will make this call when given the input
|
@@ -426,7 +440,6 @@ module ActiveSupport
|
|
426
440
|
# Filters support:
|
427
441
|
#
|
428
442
|
# Symbols:: A method to call.
|
429
|
-
# Strings:: Some content to evaluate.
|
430
443
|
# Procs:: A proc to call with the object.
|
431
444
|
# Objects:: An object with a <tt>before_foo</tt> method on it to call.
|
432
445
|
#
|
@@ -436,8 +449,6 @@ module ActiveSupport
|
|
436
449
|
case filter
|
437
450
|
when Symbol
|
438
451
|
new(nil, filter, [], nil)
|
439
|
-
when String
|
440
|
-
new(nil, :instance_exec, [:value], compile_lambda(filter))
|
441
452
|
when Conditionals::Value
|
442
453
|
new(filter, :call, [:target, :value], nil)
|
443
454
|
when ::Proc
|
@@ -454,10 +465,6 @@ module ActiveSupport
|
|
454
465
|
new(filter, method_to_call, [:target], nil)
|
455
466
|
end
|
456
467
|
end
|
457
|
-
|
458
|
-
def self.compile_lambda(filter)
|
459
|
-
eval("lambda { |value| #{filter} }")
|
460
|
-
end
|
461
468
|
end
|
462
469
|
|
463
470
|
# Execute before and after filters in a sequence instead of
|
@@ -491,9 +498,7 @@ module ActiveSupport
|
|
491
498
|
arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) }
|
492
499
|
end
|
493
500
|
|
494
|
-
|
495
|
-
@nested
|
496
|
-
end
|
501
|
+
attr_reader :nested
|
497
502
|
|
498
503
|
def final?
|
499
504
|
!@call_template
|
@@ -512,7 +517,6 @@ module ActiveSupport
|
|
512
517
|
end
|
513
518
|
end
|
514
519
|
|
515
|
-
# An Array with a compile method.
|
516
520
|
class CallbackChain #:nodoc:#
|
517
521
|
include Enumerable
|
518
522
|
|
@@ -573,10 +577,9 @@ module ActiveSupport
|
|
573
577
|
end
|
574
578
|
|
575
579
|
protected
|
576
|
-
|
580
|
+
attr_reader :chain
|
577
581
|
|
578
582
|
private
|
579
|
-
|
580
583
|
def append_one(callback)
|
581
584
|
@callbacks = nil
|
582
585
|
remove_duplicates(callback)
|
@@ -598,7 +601,7 @@ module ActiveSupport
|
|
598
601
|
Proc.new do |target, result_lambda|
|
599
602
|
terminate = true
|
600
603
|
catch(:abort) do
|
601
|
-
result_lambda.call
|
604
|
+
result_lambda.call
|
602
605
|
terminate = false
|
603
606
|
end
|
604
607
|
terminate
|
@@ -651,24 +654,25 @@ module ActiveSupport
|
|
651
654
|
#
|
652
655
|
# ===== Options
|
653
656
|
#
|
654
|
-
# * <tt>:if</tt> - A symbol
|
655
|
-
#
|
656
|
-
#
|
657
|
-
#
|
658
|
-
#
|
659
|
-
#
|
657
|
+
# * <tt>:if</tt> - A symbol or an array of symbols, each naming an instance
|
658
|
+
# method or a proc; the callback will be called only when they all return
|
659
|
+
# a true value.
|
660
|
+
#
|
661
|
+
# If a proc is given, its body is evaluated in the context of the
|
662
|
+
# current object. It can also optionally accept the current object as
|
663
|
+
# an argument.
|
664
|
+
# * <tt>:unless</tt> - A symbol or an array of symbols, each naming an
|
665
|
+
# instance method or a proc; the callback will be called only when they
|
666
|
+
# all return a false value.
|
667
|
+
#
|
668
|
+
# If a proc is given, its body is evaluated in the context of the
|
669
|
+
# current object. It can also optionally accept the current object as
|
670
|
+
# an argument.
|
660
671
|
# * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
|
661
672
|
# existing chain rather than appended.
|
662
673
|
def set_callback(name, *filter_list, &block)
|
663
674
|
type, filters, options = normalize_callback_params(filter_list, block)
|
664
675
|
|
665
|
-
if options[:if].is_a?(String) || options[:unless].is_a?(String)
|
666
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
667
|
-
Passing string to :if and :unless conditional options is deprecated
|
668
|
-
and will be removed in Rails 5.2 without replacement.
|
669
|
-
MSG
|
670
|
-
end
|
671
|
-
|
672
676
|
self_chain = get_callbacks name
|
673
677
|
mapped = filters.map do |filter|
|
674
678
|
Callback.build(self_chain, filter, type, options)
|
@@ -693,13 +697,6 @@ module ActiveSupport
|
|
693
697
|
def skip_callback(name, *filter_list, &block)
|
694
698
|
type, filters, options = normalize_callback_params(filter_list, block)
|
695
699
|
|
696
|
-
if options[:if].is_a?(String) || options[:unless].is_a?(String)
|
697
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
698
|
-
Passing string to :if and :unless conditional options is deprecated
|
699
|
-
and will be removed in Rails 5.2 without replacement.
|
700
|
-
MSG
|
701
|
-
end
|
702
|
-
|
703
700
|
options[:raise] = true unless options.key?(:raise)
|
704
701
|
|
705
702
|
__update_callbacks(name) do |target, chain|
|
@@ -758,8 +755,8 @@ module ActiveSupport
|
|
758
755
|
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
|
759
756
|
# callbacks should be terminated by the <tt>:terminator</tt> option. By
|
760
757
|
# default after callbacks are executed no matter if callback chain was
|
761
|
-
# terminated or not. This option
|
762
|
-
# option is
|
758
|
+
# terminated or not. This option has no effect if <tt>:terminator</tt>
|
759
|
+
# option is set to +nil+.
|
763
760
|
#
|
764
761
|
# * <tt>:scope</tt> - Indicates which methods should be executed when an
|
765
762
|
# object is used as a callback.
|
@@ -818,7 +815,9 @@ module ActiveSupport
|
|
818
815
|
names.each do |name|
|
819
816
|
name = name.to_sym
|
820
817
|
|
821
|
-
|
818
|
+
([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
|
819
|
+
target.set_callbacks name, CallbackChain.new(name, options)
|
820
|
+
end
|
822
821
|
|
823
822
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
824
823
|
def _run_#{name}_callbacks(&block)
|
@@ -841,13 +840,22 @@ module ActiveSupport
|
|
841
840
|
end
|
842
841
|
|
843
842
|
protected
|
844
|
-
|
845
843
|
def get_callbacks(name) # :nodoc:
|
846
844
|
__callbacks[name.to_sym]
|
847
845
|
end
|
848
846
|
|
849
|
-
|
850
|
-
|
847
|
+
if Module.instance_method(:method_defined?).arity == 1 # Ruby 2.5 and older
|
848
|
+
def set_callbacks(name, callbacks) # :nodoc:
|
849
|
+
self.__callbacks = __callbacks.merge(name.to_sym => callbacks)
|
850
|
+
end
|
851
|
+
else # Ruby 2.6 and newer
|
852
|
+
def set_callbacks(name, callbacks) # :nodoc:
|
853
|
+
unless singleton_class.method_defined?(:__callbacks, false)
|
854
|
+
self.__callbacks = __callbacks.dup
|
855
|
+
end
|
856
|
+
self.__callbacks[name.to_sym] = callbacks
|
857
|
+
self.__callbacks
|
858
|
+
end
|
851
859
|
end
|
852
860
|
end
|
853
861
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
# A typical module looks like this:
|
3
5
|
#
|
@@ -17,7 +19,7 @@ module ActiveSupport
|
|
17
19
|
# By using <tt>ActiveSupport::Concern</tt> the above module could instead be
|
18
20
|
# written as:
|
19
21
|
#
|
20
|
-
# require
|
22
|
+
# require "active_support/concern"
|
21
23
|
#
|
22
24
|
# module M
|
23
25
|
# extend ActiveSupport::Concern
|
@@ -74,7 +76,7 @@ module ActiveSupport
|
|
74
76
|
# is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
|
75
77
|
# module dependencies are properly resolved:
|
76
78
|
#
|
77
|
-
# require
|
79
|
+
# require "active_support/concern"
|
78
80
|
#
|
79
81
|
# module Foo
|
80
82
|
# extend ActiveSupport::Concern
|
@@ -97,6 +99,14 @@ module ActiveSupport
|
|
97
99
|
# class Host
|
98
100
|
# include Bar # It works, now Bar takes care of its dependencies
|
99
101
|
# end
|
102
|
+
#
|
103
|
+
# === Prepending concerns
|
104
|
+
#
|
105
|
+
# Just like <tt>include</tt>, concerns also support <tt>prepend</tt> with a corresponding
|
106
|
+
# <tt>prepended do</tt> callback. <tt>module ClassMethods</tt> or <tt>class_methods do</tt> are
|
107
|
+
# prepended as well.
|
108
|
+
#
|
109
|
+
# <tt>prepend</tt> is also used for any dependencies.
|
100
110
|
module Concern
|
101
111
|
class MultipleIncludedBlocks < StandardError #:nodoc:
|
102
112
|
def initialize
|
@@ -104,14 +114,20 @@ module ActiveSupport
|
|
104
114
|
end
|
105
115
|
end
|
106
116
|
|
117
|
+
class MultiplePrependBlocks < StandardError #:nodoc:
|
118
|
+
def initialize
|
119
|
+
super "Cannot define multiple 'prepended' blocks for a Concern"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
107
123
|
def self.extended(base) #:nodoc:
|
108
124
|
base.instance_variable_set(:@_dependencies, [])
|
109
125
|
end
|
110
126
|
|
111
|
-
def append_features(base)
|
127
|
+
def append_features(base) #:nodoc:
|
112
128
|
if base.instance_variable_defined?(:@_dependencies)
|
113
129
|
base.instance_variable_get(:@_dependencies) << self
|
114
|
-
|
130
|
+
false
|
115
131
|
else
|
116
132
|
return false if base < self
|
117
133
|
@_dependencies.each { |dep| base.include(dep) }
|
@@ -121,16 +137,73 @@ module ActiveSupport
|
|
121
137
|
end
|
122
138
|
end
|
123
139
|
|
140
|
+
def prepend_features(base) #:nodoc:
|
141
|
+
if base.instance_variable_defined?(:@_dependencies)
|
142
|
+
base.instance_variable_get(:@_dependencies).unshift self
|
143
|
+
false
|
144
|
+
else
|
145
|
+
return false if base < self
|
146
|
+
@_dependencies.each { |dep| base.prepend(dep) }
|
147
|
+
super
|
148
|
+
base.singleton_class.prepend const_get(:ClassMethods) if const_defined?(:ClassMethods)
|
149
|
+
base.class_eval(&@_prepended_block) if instance_variable_defined?(:@_prepended_block)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Evaluate given block in context of base class,
|
154
|
+
# so that you can write class macros here.
|
155
|
+
# When you define more than one +included+ block, it raises an exception.
|
124
156
|
def included(base = nil, &block)
|
125
157
|
if base.nil?
|
126
|
-
|
158
|
+
if instance_variable_defined?(:@_included_block)
|
159
|
+
if @_included_block.source_location != block.source_location
|
160
|
+
raise MultipleIncludedBlocks
|
161
|
+
end
|
162
|
+
else
|
163
|
+
@_included_block = block
|
164
|
+
end
|
165
|
+
else
|
166
|
+
super
|
167
|
+
end
|
168
|
+
end
|
127
169
|
|
128
|
-
|
170
|
+
# Evaluate given block in context of base class,
|
171
|
+
# so that you can write class macros here.
|
172
|
+
# When you define more than one +prepended+ block, it raises an exception.
|
173
|
+
def prepended(base = nil, &block)
|
174
|
+
if base.nil?
|
175
|
+
if instance_variable_defined?(:@_prepended_block)
|
176
|
+
if @_prepended_block.source_location != block.source_location
|
177
|
+
raise MultiplePrependBlocks
|
178
|
+
end
|
179
|
+
else
|
180
|
+
@_prepended_block = block
|
181
|
+
end
|
129
182
|
else
|
130
183
|
super
|
131
184
|
end
|
132
185
|
end
|
133
186
|
|
187
|
+
# Define class methods from given block.
|
188
|
+
# You can define private class methods as well.
|
189
|
+
#
|
190
|
+
# module Example
|
191
|
+
# extend ActiveSupport::Concern
|
192
|
+
#
|
193
|
+
# class_methods do
|
194
|
+
# def foo; puts 'foo'; end
|
195
|
+
#
|
196
|
+
# private
|
197
|
+
# def bar; puts 'bar'; end
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# class Buzz
|
202
|
+
# include Example
|
203
|
+
# end
|
204
|
+
#
|
205
|
+
# Buzz.foo # => "foo"
|
206
|
+
# Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError)
|
134
207
|
def class_methods(&class_methods_module_definition)
|
135
208
|
mod = const_defined?(:ClassMethods, false) ?
|
136
209
|
const_get(:ClassMethods) :
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "monitor"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module Concurrency
|
7
|
+
# A monitor that will permit dependency loading while blocked waiting for
|
8
|
+
# the lock.
|
9
|
+
class LoadInterlockAwareMonitor < Monitor
|
10
|
+
EXCEPTION_NEVER = { Exception => :never }.freeze
|
11
|
+
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze
|
12
|
+
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
13
|
+
|
14
|
+
# Enters an exclusive section, but allows dependency loading while blocked
|
15
|
+
def mon_enter
|
16
|
+
mon_try_enter ||
|
17
|
+
ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
|
18
|
+
end
|
19
|
+
|
20
|
+
def synchronize
|
21
|
+
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
22
|
+
mon_enter
|
23
|
+
|
24
|
+
begin
|
25
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
|
26
|
+
yield
|
27
|
+
end
|
28
|
+
ensure
|
29
|
+
mon_exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "thread"
|
2
4
|
require "monitor"
|
3
5
|
|
@@ -198,7 +200,6 @@ module ActiveSupport
|
|
198
200
|
end
|
199
201
|
|
200
202
|
private
|
201
|
-
|
202
203
|
# Must be called within synchronize
|
203
204
|
def busy_for_exclusive?(purpose)
|
204
205
|
busy_for_sharing?(purpose) ||
|
@@ -1,11 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/concern"
|
2
4
|
require "active_support/ordered_options"
|
3
|
-
require "active_support/core_ext/array/extract_options"
|
4
|
-
require "active_support/core_ext/regexp"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
7
|
# Configurable provides a <tt>config</tt> method to store and retrieve
|
8
|
-
# configuration options as an <tt>
|
8
|
+
# configuration options as an <tt>OrderedOptions</tt>.
|
9
9
|
module Configurable
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
|
@@ -67,8 +67,8 @@ module ActiveSupport
|
|
67
67
|
# end
|
68
68
|
# # => NameError: invalid config attribute name
|
69
69
|
#
|
70
|
-
# To
|
71
|
-
# To
|
70
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
71
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
72
72
|
#
|
73
73
|
# class User
|
74
74
|
# include ActiveSupport::Configurable
|
@@ -81,7 +81,7 @@ module ActiveSupport
|
|
81
81
|
# User.new.allowed_access = true # => NoMethodError
|
82
82
|
# User.new.allowed_access # => NoMethodError
|
83
83
|
#
|
84
|
-
# Or pass <tt>instance_accessor: false</tt>, to
|
84
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
85
85
|
#
|
86
86
|
# class User
|
87
87
|
# include ActiveSupport::Configurable
|
@@ -104,9 +104,7 @@ module ActiveSupport
|
|
104
104
|
# end
|
105
105
|
#
|
106
106
|
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
107
|
-
def config_accessor(*names)
|
108
|
-
options = names.extract_options!
|
109
|
-
|
107
|
+
def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
|
110
108
|
names.each do |name|
|
111
109
|
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
|
112
110
|
|
@@ -116,9 +114,9 @@ module ActiveSupport
|
|
116
114
|
singleton_class.class_eval reader, __FILE__, reader_line
|
117
115
|
singleton_class.class_eval writer, __FILE__, writer_line
|
118
116
|
|
119
|
-
|
120
|
-
class_eval reader, __FILE__, reader_line
|
121
|
-
class_eval writer, __FILE__, writer_line
|
117
|
+
if instance_accessor
|
118
|
+
class_eval reader, __FILE__, reader_line if instance_reader
|
119
|
+
class_eval writer, __FILE__, writer_line if instance_writer
|
122
120
|
end
|
123
121
|
send("#{name}=", yield) if block_given?
|
124
122
|
end
|
@@ -126,9 +124,9 @@ module ActiveSupport
|
|
126
124
|
private :config_accessor
|
127
125
|
end
|
128
126
|
|
129
|
-
# Reads and writes attributes from a configuration <tt>
|
127
|
+
# Reads and writes attributes from a configuration <tt>OrderedOptions</tt>.
|
130
128
|
#
|
131
|
-
# require
|
129
|
+
# require "active_support/configurable"
|
132
130
|
#
|
133
131
|
# class User
|
134
132
|
# include ActiveSupport::Configurable
|