activesupport 7.0.2.4 → 7.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/lib/active_support/backtrace_cleaner.rb +2 -2
  4. data/lib/active_support/cache/mem_cache_store.rb +21 -5
  5. data/lib/active_support/cache/memory_store.rb +1 -1
  6. data/lib/active_support/cache/redis_cache_store.rb +17 -11
  7. data/lib/active_support/cache/strategy/local_cache.rb +3 -0
  8. data/lib/active_support/cache.rb +122 -114
  9. data/lib/active_support/callbacks.rb +5 -5
  10. data/lib/active_support/configurable.rb +2 -2
  11. data/lib/active_support/core_ext/array/conversions.rb +0 -1
  12. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  13. data/lib/active_support/core_ext/date/calculations.rb +5 -5
  14. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  15. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  16. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  17. data/lib/active_support/core_ext/enumerable.rb +26 -9
  18. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  19. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  20. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  21. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +4 -4
  22. data/lib/active_support/core_ext/numeric/conversions.rb +1 -1
  23. data/lib/active_support/core_ext/object/json.rb +1 -1
  24. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  25. data/lib/active_support/core_ext/securerandom.rb +1 -1
  26. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  27. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  28. data/lib/active_support/core_ext/string/output_safety.rb +3 -3
  29. data/lib/active_support/core_ext/time/calculations.rb +2 -2
  30. data/lib/active_support/core_ext/time/zones.rb +3 -3
  31. data/lib/active_support/deprecation/behaviors.rb +4 -4
  32. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  33. data/lib/active_support/deprecation.rb +1 -1
  34. data/lib/active_support/encrypted_file.rb +12 -0
  35. data/lib/active_support/error_reporter.rb +2 -2
  36. data/lib/active_support/evented_file_update_checker.rb +2 -4
  37. data/lib/active_support/gem_version.rb +3 -3
  38. data/lib/active_support/inflector/transliterate.rb +1 -1
  39. data/lib/active_support/isolated_execution_state.rb +8 -0
  40. data/lib/active_support/key_generator.rb +4 -4
  41. data/lib/active_support/lazy_load_hooks.rb +28 -4
  42. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  43. data/lib/active_support/log_subscriber.rb +2 -2
  44. data/lib/active_support/message_encryptor.rb +4 -3
  45. data/lib/active_support/notifications.rb +8 -2
  46. data/lib/active_support/option_merger.rb +2 -2
  47. data/lib/active_support/ordered_options.rb +1 -1
  48. data/lib/active_support/railtie.rb +5 -5
  49. data/lib/active_support/rescuable.rb +10 -10
  50. data/lib/active_support/secure_compare_rotator.rb +1 -1
  51. data/lib/active_support/test_case.rb +4 -0
  52. data/lib/active_support/testing/assertions.rb +1 -1
  53. data/lib/active_support/time_with_zone.rb +6 -7
  54. data/lib/active_support/values/time_zone.rb +5 -5
  55. data/lib/active_support/version.rb +1 -1
  56. metadata +6 -6
@@ -201,7 +201,7 @@ module DateAndTime
201
201
  end
202
202
  end
203
203
 
204
- # Short-hand for months_since(3)
204
+ # Short-hand for <tt>months_since(3)</tt>.
205
205
  def next_quarter
206
206
  months_since(3)
207
207
  end
@@ -226,18 +226,18 @@ module DateAndTime
226
226
  end
227
227
  alias_method :last_weekday, :prev_weekday
228
228
 
229
- # Short-hand for months_ago(1).
229
+ # Short-hand for <tt>months_ago(1)</tt>.
230
230
  def last_month
231
231
  months_ago(1)
232
232
  end
233
233
 
234
- # Short-hand for months_ago(3).
234
+ # Short-hand for <tt>months_ago(3)</tt>.
235
235
  def prev_quarter
236
236
  months_ago(3)
237
237
  end
238
238
  alias_method :last_quarter, :prev_quarter
239
239
 
240
- # Short-hand for years_ago(1).
240
+ # Short-hand for <tt>years_ago(1)</tt>.
241
241
  def last_year
242
242
  years_ago(1)
243
243
  end
@@ -15,7 +15,7 @@ module DateAndTime
15
15
 
16
16
  # Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
17
17
  #
18
- # When `true`, it returns local times with a UTC offset, with `false` local
18
+ # When +true+, it returns local times with a UTC offset, with +false+ local
19
19
  # times are returned as UTC.
20
20
  #
21
21
  # # Given this zone:
@@ -1,13 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Enumerable
4
- INDEX_WITH_DEFAULT = Object.new
5
- private_constant :INDEX_WITH_DEFAULT
3
+ module ActiveSupport
4
+ module EnumerableCoreExt # :nodoc:
5
+ module Constants
6
+ private
7
+ def const_missing(name)
8
+ if name == :SoleItemExpectedError
9
+ ::ActiveSupport::EnumerableCoreExt::SoleItemExpectedError
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
6
17
 
18
+ module Enumerable
7
19
  # Error generated by +sole+ when called on an enumerable that doesn't have
8
20
  # exactly one item.
9
21
  class SoleItemExpectedError < StandardError; end
10
22
 
23
+ # HACK: For performance reasons, Enumerable shouldn't have any constants of its own.
24
+ # So we move SoleItemExpectedError into ActiveSupport::EnumerableCoreExt.
25
+ ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError)
26
+ singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants)
27
+
11
28
  # Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
12
29
  # when we omit an identity.
13
30
 
@@ -106,17 +123,17 @@ module Enumerable
106
123
  #
107
124
  # %i( created_at updated_at ).index_with(Time.now)
108
125
  # # => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 }
109
- def index_with(default = INDEX_WITH_DEFAULT)
126
+ def index_with(default = (no_default = true))
110
127
  if block_given?
111
128
  result = {}
112
129
  each { |elem| result[elem] = yield(elem) }
113
130
  result
114
- elsif default != INDEX_WITH_DEFAULT
131
+ elsif no_default
132
+ to_enum(:index_with) { size if respond_to?(:size) }
133
+ else
115
134
  result = {}
116
135
  each { |elem| result[elem] = default }
117
136
  result
118
- else
119
- to_enum(:index_with) { size if respond_to?(:size) }
120
137
  end
121
138
  end
122
139
 
@@ -240,8 +257,8 @@ module Enumerable
240
257
  def sole
241
258
  case count
242
259
  when 1 then return first # rubocop:disable Style/RedundantReturn
243
- when 0 then raise SoleItemExpectedError, "no item found"
244
- when 2.. then raise SoleItemExpectedError, "multiple items found"
260
+ when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
261
+ when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
245
262
  end
246
263
  end
247
264
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/xml_mini"
4
3
  require "active_support/core_ext/object/blank"
5
4
  require "active_support/core_ext/object/to_param"
6
5
  require "active_support/core_ext/object/to_query"
@@ -3,7 +3,7 @@
3
3
  require "active_support/hash_with_indifferent_access"
4
4
 
5
5
  class Hash
6
- # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
6
+ # Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver:
7
7
  #
8
8
  # { a: 1 }.with_indifferent_access['a'] # => 1
9
9
  def with_indifferent_access
@@ -13,8 +13,8 @@ class Hash
13
13
  # Called when object is nested under an object that receives
14
14
  # #with_indifferent_access. This method will be called on the current object
15
15
  # by the enclosing object and is aliased to #with_indifferent_access by
16
- # default. Subclasses of Hash may overwrite this method to return +self+ if
17
- # converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
16
+ # default. Subclasses of Hash may override this method to return +self+ if
17
+ # converting to an ActiveSupport::HashWithIndifferentAccess would not be
18
18
  # desirable.
19
19
  #
20
20
  # b = { b: 1 }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kernel
4
- # class_eval on an object acts like singleton_class.class_eval.
4
+ # class_eval on an object acts like +singleton_class.class_eval+.
5
5
  def class_eval(*args, &block)
6
6
  singleton_class.class_eval(*args, &block)
7
7
  end
@@ -9,8 +9,8 @@
9
9
  # So the values are scoped within the Thread.current space under the class name
10
10
  # of the module.
11
11
  #
12
- # Note that it can also be scoped per-fiber if Rails.application.config.active_support.isolation_level
13
- # is set to `:fiber`
12
+ # Note that it can also be scoped per-fiber if +Rails.application.config.active_support.isolation_level+
13
+ # is set to +:fiber+.
14
14
  class Module
15
15
  # Defines a per-thread class attribute and creates class and instance reader methods.
16
16
  # The underlying per-thread class variable is set to +nil+, if it is not previously defined.
@@ -21,7 +21,7 @@ class Module
21
21
  #
22
22
  # Current.user = "DHH"
23
23
  # Current.user # => "DHH"
24
- # Thread.new { Current.user }.values # => nil
24
+ # Thread.new { Current.user }.value # => nil
25
25
  #
26
26
  # The attribute name must be a valid method name in Ruby.
27
27
  #
@@ -118,7 +118,7 @@ class Module
118
118
  # Account.user # => "DHH"
119
119
  # Account.new.user # => "DHH"
120
120
  #
121
- # Unlike `mattr_accessor`, values are *not* shared with subclasses or parent classes.
121
+ # Unlike +mattr_accessor+, values are *not* shared with subclasses or parent classes.
122
122
  # If a subclass changes the value, the parent class' value is not changed.
123
123
  # If the parent class changes the value, the value of subclasses is not changed.
124
124
  #
@@ -7,7 +7,7 @@ module ActiveSupport
7
7
  module NumericWithFormat
8
8
  # Provides options for converting numbers into formatted strings.
9
9
  # Options are provided for phone numbers, currency, percentage,
10
- # precision, positional notation, file size and pretty printing.
10
+ # precision, positional notation, file size, and pretty printing.
11
11
  #
12
12
  # This method is aliased to <tt>to_formatted_s</tt>.
13
13
  #
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Hack to load json gem first so we can overwrite its to_json.
3
+ # Hack to load json gem first so we can override its to_json.
4
4
  require "json"
5
5
  require "bigdecimal"
6
6
  require "ipaddr"
@@ -5,6 +5,6 @@ class Range
5
5
  # (1..5).overlaps?(4..6) # => true
6
6
  # (1..5).overlaps?(7..9) # => false
7
7
  def overlaps?(other)
8
- cover?(other.first) || other.cover?(first)
8
+ other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin)
9
9
  end
10
10
  end
@@ -12,7 +12,7 @@ module SecureRandom
12
12
  #
13
13
  # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future.
14
14
  #
15
- # The result may contain alphanumeric characters except 0, O, I and l.
15
+ # The result may contain alphanumeric characters except 0, O, I, and l.
16
16
  #
17
17
  # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
18
18
  # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
@@ -5,10 +5,10 @@ require "active_support/core_ext/time/calculations"
5
5
 
6
6
  class String
7
7
  # Converts a string to a Time value.
8
- # The +form+ can be either :utc or :local (default :local).
8
+ # The +form+ can be either +:utc+ or +:local+ (default +:local+).
9
9
  #
10
10
  # The time is parsed using Time.parse method.
11
- # If +form+ is :local, then the time is in the system timezone.
11
+ # If +form+ is +:local+, then the time is in the system timezone.
12
12
  # If the date part is missing then the current date is used and if
13
13
  # the time part is missing then it is assumed to be 00:00:00.
14
14
  #
@@ -4,7 +4,7 @@ require "active_support/string_inquirer"
4
4
  require "active_support/environment_inquirer"
5
5
 
6
6
  class String
7
- # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
7
+ # Wraps the current string in the ActiveSupport::StringInquirer class,
8
8
  # which gives you a prettier way to test for equality.
9
9
  #
10
10
  # env = 'production'.inquiry
@@ -12,7 +12,7 @@ class ERB
12
12
  JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
13
13
 
14
14
  # Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
15
- TAG_NAME_START_REGEXP_SET = ":A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
15
+ TAG_NAME_START_REGEXP_SET = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
16
16
  "\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
17
17
  "\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
18
18
  TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}]/
@@ -105,7 +105,7 @@ class ERB
105
105
  # WARNING: this helper only works with valid JSON. Using this on non-JSON values
106
106
  # will open up serious XSS vulnerabilities. For example, if you replace the
107
107
  # +current_user.to_json+ in the example above with user input instead, the browser
108
- # will happily eval() that string as JavaScript.
108
+ # will happily <tt>eval()</tt> that string as JavaScript.
109
109
  #
110
110
  # The escaping performed in this method is identical to those performed in the
111
111
  # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
@@ -171,7 +171,7 @@ module ActiveSupport # :nodoc:
171
171
  alias_method :original_concat, :concat
172
172
  private :original_concat
173
173
 
174
- # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
174
+ # Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.
175
175
  class SafeConcatError < StandardError
176
176
  def initialize
177
177
  super "Could not concatenate to the buffer because it is not html safe."
@@ -126,8 +126,8 @@ class Time
126
126
  # Returns a new Time where one or more of the elements have been changed according
127
127
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
128
128
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
129
- # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
130
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
129
+ # the hour is passed, then minute, sec, usec, and nsec is set to 0. If the hour
130
+ # and minute is passed, then sec, usec, and nsec is set to 0. The +options+ parameter
131
131
  # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
132
132
  # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
133
133
  # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
@@ -21,8 +21,8 @@ class Time
21
21
  #
22
22
  # * A Rails TimeZone object.
23
23
  # * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
24
- # * A TZInfo::Timezone object.
25
- # * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
24
+ # * A <tt>TZInfo::Timezone</tt> object.
25
+ # * An identifier for a <tt>TZInfo::Timezone</tt> object (e.g., "America/New_York").
26
26
  #
27
27
  # Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
28
28
  # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
@@ -55,7 +55,7 @@ class Time
55
55
  # end
56
56
  # end
57
57
  #
58
- # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
58
+ # NOTE: This won't affect any ActiveSupport::TimeWithZone
59
59
  # objects that have already been created, e.g. any model timestamp
60
60
  # attributes that have been read before the block will remain in
61
61
  # the application's default timezone.
@@ -3,7 +3,7 @@
3
3
  require "active_support/notifications"
4
4
 
5
5
  module ActiveSupport
6
- # Raised when <tt>ActiveSupport::Deprecation::Behavior#behavior</tt> is set with <tt>:raise</tt>.
6
+ # Raised when ActiveSupport::Deprecation::Behavior#behavior is set with <tt>:raise</tt>.
7
7
  # You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
8
8
  class DeprecationException < StandardError
9
9
  end
@@ -114,10 +114,10 @@ module ActiveSupport
114
114
  raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
115
115
  end
116
116
 
117
- if behavior.arity == 4 || behavior.arity == -1
118
- behavior
119
- else
117
+ if behavior.respond_to?(:arity) && behavior.arity == 2
120
118
  -> message, callstack, _, _ { behavior.call(message, callstack) }
119
+ else
120
+ behavior
121
121
  end
122
122
  end
123
123
  end
@@ -26,7 +26,7 @@ module ActiveSupport
26
26
  end
27
27
 
28
28
  # DeprecatedObjectProxy transforms an object into a deprecated one. It
29
- # takes an object, a deprecation message and optionally a deprecator. The
29
+ # takes an object, a deprecation message, and optionally a deprecator. The
30
30
  # deprecator defaults to +ActiveSupport::Deprecator+ if none is specified.
31
31
  #
32
32
  # deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated")
@@ -4,7 +4,7 @@ require "singleton"
4
4
 
5
5
  module ActiveSupport
6
6
  # \Deprecation specifies the API used by Rails to deprecate methods, instance
7
- # variables, objects and constants.
7
+ # variables, objects, and constants.
8
8
  class Deprecation
9
9
  # active_support.rb sets an autoload for ActiveSupport::Deprecation.
10
10
  #
@@ -45,10 +45,22 @@ module ActiveSupport
45
45
  @env_key, @raise_if_missing_key = env_key, raise_if_missing_key
46
46
  end
47
47
 
48
+ # Returns the encryption key, first trying the environment variable
49
+ # specified by +env_key+, then trying the key file specified by +key_path+.
50
+ # If +raise_if_missing_key+ is true, raises MissingKeyError if the
51
+ # environment variable is not set and the key file does not exist.
48
52
  def key
49
53
  read_env_key || read_key_file || handle_missing_key
50
54
  end
51
55
 
56
+ # Reads the file and returns the decrypted content.
57
+ #
58
+ # Raises:
59
+ # - MissingKeyError if the key is missing and +raise_if_missing_key+ is true.
60
+ # - MissingContentError if the encrypted file does not exist or otherwise
61
+ # if the key is missing.
62
+ # - ActiveSupport::MessageEncryptor::InvalidMessage if the content cannot be
63
+ # decrypted or verified.
52
64
  def read
53
65
  if !key.nil? && content_path.exist?
54
66
  decrypt content_path.binread
@@ -28,8 +28,8 @@ module ActiveSupport
28
28
  # end
29
29
  #
30
30
  # Additionally a +severity+ can be passed along to communicate how important the error report is.
31
- # +severity+ can be one of +:error+, +:warning+ or +:info+. Handled errors default to the +:warning+
32
- # severity, and unhandled ones to +error+.
31
+ # +severity+ can be one of +:error+, +:warning+, or +:info+. Handled errors default to the +:warning+
32
+ # severity, and unhandled ones to +:error+.
33
33
  #
34
34
  # Both +handle+ and +record+ pass through the return value from the block. In the case of +handle+
35
35
  # rescuing an error, a fallback can be provided. The fallback must be a callable whose result will
@@ -8,8 +8,8 @@ require "active_support/fork_tracker"
8
8
 
9
9
  module ActiveSupport
10
10
  # Allows you to "listen" to changes in a file system.
11
- # The evented file updater does not hit disk when checking for updates
12
- # instead it uses platform specific file system events to trigger a change
11
+ # The evented file updater does not hit disk when checking for updates.
12
+ # Instead, it uses platform-specific file system events to trigger a change
13
13
  # in state.
14
14
  #
15
15
  # The file checker takes an array of files to watch or a hash specifying directories
@@ -17,8 +17,6 @@ module ActiveSupport
17
17
  # EventedFileUpdateChecker#execute is run or when EventedFileUpdateChecker#execute_if_updated
18
18
  # is run and there have been changes to the file system.
19
19
  #
20
- # Note: Forking will cause the first call to `updated?` to return `true`.
21
- #
22
20
  # Example:
23
21
  #
24
22
  # checker = ActiveSupport::EventedFileUpdateChecker.new(["/tmp/foo"]) { puts "changed" }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
4
+ # Returns the currently loaded version of Active Support as a <tt>Gem::Version</tt>.
5
5
  def self.gem_version
6
6
  Gem::Version.new VERSION::STRING
7
7
  end
@@ -9,8 +9,8 @@ module ActiveSupport
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 2
13
- PRE = "4"
12
+ TINY = 4
13
+ PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -59,7 +59,7 @@ module ActiveSupport
59
59
  # transliterate('Jürgen', locale: :de)
60
60
  # # => "Juergen"
61
61
  #
62
- # Transliteration is restricted to UTF-8, US-ASCII and GB18030 strings
62
+ # Transliteration is restricted to UTF-8, US-ASCII, and GB18030 strings.
63
63
  # Other encodings will raise an ArgumentError.
64
64
  def transliterate(string, replacement = "?", locale: nil)
65
65
  string = string.dup if string.frozen?
@@ -49,6 +49,14 @@ module ActiveSupport
49
49
  current.clear
50
50
  end
51
51
 
52
+ def share_with(other)
53
+ # Action Controller streaming spawns a new thread and copy thread locals.
54
+ # We do the same here for backward compatibility, but this is very much a hack
55
+ # and streaming should be rethought.
56
+ context = @isolation_level == :thread ? Thread.current : Fiber.current
57
+ context.active_support_execution_state = other.active_support_execution_state.dup
58
+ end
59
+
52
60
  private
53
61
  def current_thread
54
62
  Thread.current.active_support_execution_state ||= {}
@@ -33,17 +33,17 @@ module ActiveSupport
33
33
  @hash_digest_class = options[:hash_digest_class] || self.class.hash_digest_class
34
34
  end
35
35
 
36
- # Returns a derived key suitable for use. The default key_size is chosen
36
+ # Returns a derived key suitable for use. The default +key_size+ is chosen
37
37
  # to be compatible with the default settings of ActiveSupport::MessageVerifier.
38
- # i.e. OpenSSL::Digest::SHA1#block_length
38
+ # i.e. <tt>OpenSSL::Digest::SHA1#block_length</tt>
39
39
  def generate_key(salt, key_size = 64)
40
40
  OpenSSL::PKCS5.pbkdf2_hmac(@secret, salt, @iterations, key_size, @hash_digest_class.new)
41
41
  end
42
42
  end
43
43
 
44
44
  # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
45
- # re-executing the key generation process when it's called using the same salt and
46
- # key_size.
45
+ # re-executing the key generation process when it's called using the same +salt+ and
46
+ # +key_size+.
47
47
  class CachingKeyGenerator
48
48
  def initialize(key_generator)
49
49
  @key_generator = key_generator
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- # lazy_load_hooks allows Rails to lazily load a lot of components and thus
4
+ # LazyLoadHooks allows Rails to lazily load a lot of components and thus
5
5
  # making the app boot faster. Because of this feature now there is no need to
6
6
  # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
7
7
  # configuration. Instead a hook is registered that applies configuration once
8
8
  # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
9
9
  # used as example but this feature can be applied elsewhere too.
10
10
  #
11
- # Here is an example where +on_load+ method is called to register a hook.
11
+ # Here is an example where on_load method is called to register a hook.
12
12
  #
13
13
  # initializer 'active_record.initialize_timezone' do
14
14
  # ActiveSupport.on_load(:active_record) do
@@ -18,10 +18,26 @@ module ActiveSupport
18
18
  # end
19
19
  #
20
20
  # When the entirety of +ActiveRecord::Base+ has been
21
- # evaluated then +run_load_hooks+ is invoked. The very last line of
21
+ # evaluated then run_load_hooks is invoked. The very last line of
22
22
  # +ActiveRecord::Base+ is:
23
23
  #
24
24
  # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
25
+ #
26
+ # run_load_hooks will then execute all the hooks that were registered
27
+ # with the on_load method. In the case of the above example, it will
28
+ # execute the block of code that is in the +initializer+.
29
+ #
30
+ # Registering a hook that has already run results in that hook executing
31
+ # immediately. This allows hooks to be nested for code that relies on
32
+ # multiple lazily loaded components:
33
+ #
34
+ # initializer "action_text.renderer" do
35
+ # ActiveSupport.on_load(:action_controller_base) do
36
+ # ActiveSupport.on_load(:action_text_content) do
37
+ # self.default_renderer = Class.new(ActionController::Base).renderer
38
+ # end
39
+ # end
40
+ # end
25
41
  module LazyLoadHooks
26
42
  def self.extended(base) # :nodoc:
27
43
  base.class_eval do
@@ -32,7 +48,8 @@ module ActiveSupport
32
48
  end
33
49
 
34
50
  # Declares a block that will be executed when a Rails component is fully
35
- # loaded.
51
+ # loaded. If the component has already loaded, the block is executed
52
+ # immediately.
36
53
  #
37
54
  # Options:
38
55
  #
@@ -46,6 +63,13 @@ module ActiveSupport
46
63
  @load_hooks[name] << [block, options]
47
64
  end
48
65
 
66
+ # Executes all blocks registered to +name+ via on_load, using +base+ as the
67
+ # evaluation context.
68
+ #
69
+ # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
70
+ #
71
+ # In the case of the above example, it will execute all hooks registered
72
+ # for +:active_record+ within the class +ActiveRecord::Base+.
49
73
  def run_load_hooks(name, base = Object)
50
74
  @loaded[name] << base
51
75
  @load_hooks[name].each do |hook, options|
@@ -27,13 +27,13 @@ module ActiveSupport
27
27
  #
28
28
  # All you need to do is to ensure that your log subscriber is added to
29
29
  # Rails::Subscriber, as in the second line of the code above. The test
30
- # helpers are responsible for setting up the queue, subscriptions and
30
+ # helpers are responsible for setting up the queue and subscriptions, and
31
31
  # turning colors in logs off.
32
32
  #
33
33
  # The messages are available in the @logger instance, which is a logger with
34
34
  # limited powers (it actually does not send anything to your output), and
35
35
  # you can collect them doing @logger.logged(level), where level is the level
36
- # used in logging, like info, debug, warn and so on.
36
+ # used in logging, like info, debug, warn, and so on.
37
37
  module TestHelper
38
38
  def setup # :nodoc:
39
39
  @logger = MockLogger.new
@@ -6,7 +6,7 @@ require "active_support/subscriber"
6
6
 
7
7
  module ActiveSupport
8
8
  # <tt>ActiveSupport::LogSubscriber</tt> is an object set to consume
9
- # <tt>ActiveSupport::Notifications</tt> with the sole purpose of logging them.
9
+ # ActiveSupport::Notifications with the sole purpose of logging them.
10
10
  # The log subscriber dispatches notifications to a registered object based
11
11
  # on its given namespace.
12
12
  #
@@ -36,7 +36,7 @@ module ActiveSupport
36
36
  # it will properly dispatch the event
37
37
  # (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method.
38
38
  #
39
- # Being an <tt>ActiveSupport::Notifications</tt> consumer,
39
+ # Being an ActiveSupport::Notifications consumer,
40
40
  # <tt>ActiveSupport::LogSubscriber</tt> exposes a simple interface to check if
41
41
  # instrumented code raises an exception. It is common to log a different
42
42
  # message in case of an error, and this can be achieved by extending
@@ -13,7 +13,7 @@ module ActiveSupport
13
13
  # The cipher text and initialization vector are base64 encoded and returned
14
14
  # to you.
15
15
  #
16
- # This can be used in situations similar to the <tt>MessageVerifier</tt>, but
16
+ # This can be used in situations similar to the MessageVerifier, but
17
17
  # where you don't want users to be able to determine the value of the payload.
18
18
  #
19
19
  # len = ActiveSupport::MessageEncryptor.key_len
@@ -22,6 +22,7 @@ module ActiveSupport
22
22
  # crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
23
23
  # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
24
24
  # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
25
+ #
25
26
  # The +decrypt_and_verify+ method will raise an
26
27
  # <tt>ActiveSupport::MessageEncryptor::InvalidMessage</tt> exception if the data
27
28
  # provided cannot be decrypted or verified.
@@ -124,10 +125,10 @@ module ActiveSupport
124
125
  # Initialize a new MessageEncryptor. +secret+ must be at least as long as
125
126
  # the cipher key size. For the default 'aes-256-gcm' cipher, this is 256
126
127
  # bits. If you are using a user-entered secret, you can generate a suitable
127
- # key by using <tt>ActiveSupport::KeyGenerator</tt> or a similar key
128
+ # key by using ActiveSupport::KeyGenerator or a similar key
128
129
  # derivation function.
129
130
  #
130
- # First additional parameter is used as the signature key for +MessageVerifier+.
131
+ # First additional parameter is used as the signature key for MessageVerifier.
131
132
  # This allows you to specify keys to encrypt and sign data.
132
133
  #
133
134
  # ActiveSupport::MessageEncryptor.new('secret', 'signature_secret')
@@ -4,7 +4,7 @@ require "active_support/notifications/instrumenter"
4
4
  require "active_support/notifications/fanout"
5
5
 
6
6
  module ActiveSupport
7
- # = Notifications
7
+ # = \Notifications
8
8
  #
9
9
  # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
10
10
  # Ruby.
@@ -84,7 +84,7 @@ module ActiveSupport
84
84
  # event.payload[:exception] # => ["ArgumentError", "Invalid value"]
85
85
  # event.payload[:exception_object] # => #<ArgumentError: Invalid value>
86
86
  #
87
- # As the earlier example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
87
+ # As the earlier example depicts, the class ActiveSupport::Notifications::Event
88
88
  # is able to take the arguments as they come and provide an object-oriented
89
89
  # interface to that data.
90
90
  #
@@ -244,6 +244,12 @@ module ActiveSupport
244
244
  notifier.subscribe(pattern, callback, monotonic: false, &block)
245
245
  end
246
246
 
247
+ # Performs the same functionality as #subscribe, but the +start+ and
248
+ # +finish+ block arguments are in monotonic time instead of wall-clock
249
+ # time. Monotonic time will not jump forward or backward (due to NTP or
250
+ # Daylights Savings). Use +monotonic_subscribe+ when accuracy of time
251
+ # duration is important. For example, computing elapsed time between
252
+ # two events.
247
253
  def monotonic_subscribe(pattern = nil, callback = nil, &block)
248
254
  notifier.subscribe(pattern, callback, monotonic: true, &block)
249
255
  end