activesupport 4.2.11.3 → 5.0.7.2

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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +678 -348
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +2 -3
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +1 -1
  7. data/lib/active_support/benchmarkable.rb +1 -1
  8. data/lib/active_support/cache/file_store.rb +36 -22
  9. data/lib/active_support/cache/mem_cache_store.rb +63 -54
  10. data/lib/active_support/cache/memory_store.rb +16 -21
  11. data/lib/active_support/cache/null_store.rb +1 -4
  12. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  13. data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -4
  14. data/lib/active_support/cache.rb +71 -87
  15. data/lib/active_support/callbacks.rb +109 -113
  16. data/lib/active_support/concern.rb +1 -1
  17. data/lib/active_support/concurrency/latch.rb +11 -12
  18. data/lib/active_support/concurrency/share_lock.rb +226 -0
  19. data/lib/active_support/configurable.rb +1 -0
  20. data/lib/active_support/core_ext/array/access.rb +27 -1
  21. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  22. data/lib/active_support/core_ext/array/grouping.rb +9 -18
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/array.rb +1 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +3 -2
  29. data/lib/active_support/core_ext/class.rb +0 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +7 -6
  33. data/lib/active_support/core_ext/date.rb +1 -1
  34. data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
  35. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
  36. data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
  37. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  38. data/lib/active_support/core_ext/date_time/calculations.rb +14 -8
  39. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  40. data/lib/active_support/core_ext/date_time.rb +1 -1
  41. data/lib/active_support/core_ext/enumerable.rb +75 -25
  42. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  43. data/lib/active_support/core_ext/hash/conversions.rb +22 -2
  44. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  45. data/lib/active_support/core_ext/hash/except.rb +9 -8
  46. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  47. data/lib/active_support/core_ext/hash/keys.rb +25 -21
  48. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  49. data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
  50. data/lib/active_support/core_ext/integer/time.rb +2 -2
  51. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  53. data/lib/active_support/core_ext/kernel/reporting.rb +2 -84
  54. data/lib/active_support/core_ext/kernel.rb +0 -1
  55. data/lib/active_support/core_ext/load_error.rb +5 -2
  56. data/lib/active_support/core_ext/marshal.rb +7 -9
  57. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  58. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  62. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  63. data/lib/active_support/core_ext/module/delegation.rb +11 -20
  64. data/lib/active_support/core_ext/module/deprecation.rb +2 -2
  65. data/lib/active_support/core_ext/module/introspection.rb +8 -2
  66. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  67. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  68. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  69. data/lib/active_support/core_ext/module.rb +1 -0
  70. data/lib/active_support/core_ext/name_error.rb +15 -2
  71. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  72. data/lib/active_support/core_ext/numeric/conversions.rb +78 -77
  73. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  74. data/lib/active_support/core_ext/numeric/time.rb +26 -6
  75. data/lib/active_support/core_ext/numeric.rb +1 -0
  76. data/lib/active_support/core_ext/object/blank.rb +15 -3
  77. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  78. data/lib/active_support/core_ext/object/duplicable.rb +7 -12
  79. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  80. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  81. data/lib/active_support/core_ext/object/json.rb +15 -7
  82. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  83. data/lib/active_support/core_ext/object/try.rb +67 -21
  84. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  85. data/lib/active_support/core_ext/object.rb +0 -1
  86. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  87. data/lib/active_support/core_ext/range/each.rb +16 -18
  88. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  89. data/lib/active_support/core_ext/securerandom.rb +23 -0
  90. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  91. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  92. data/lib/active_support/core_ext/string/filters.rb +1 -2
  93. data/lib/active_support/core_ext/string/inflections.rb +32 -5
  94. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  95. data/lib/active_support/core_ext/string/output_safety.rb +12 -14
  96. data/lib/active_support/core_ext/string/strip.rb +3 -6
  97. data/lib/active_support/core_ext/struct.rb +3 -6
  98. data/lib/active_support/core_ext/time/calculations.rb +18 -9
  99. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  100. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  101. data/lib/active_support/core_ext/time/zones.rb +36 -4
  102. data/lib/active_support/core_ext/time.rb +0 -1
  103. data/lib/active_support/core_ext/uri.rb +1 -3
  104. data/lib/active_support/core_ext.rb +2 -1
  105. data/lib/active_support/dependencies/interlock.rb +55 -0
  106. data/lib/active_support/dependencies.rb +88 -95
  107. data/lib/active_support/deprecation/behaviors.rb +15 -1
  108. data/lib/active_support/deprecation/instance_delegator.rb +13 -0
  109. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  110. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  111. data/lib/active_support/deprecation/reporting.rb +23 -5
  112. data/lib/active_support/deprecation.rb +1 -1
  113. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  114. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  115. data/lib/active_support/duration.rb +90 -15
  116. data/lib/active_support/evented_file_update_checker.rb +199 -0
  117. data/lib/active_support/execution_wrapper.rb +126 -0
  118. data/lib/active_support/executor.rb +6 -0
  119. data/lib/active_support/file_update_checker.rb +23 -3
  120. data/lib/active_support/gem_version.rb +5 -5
  121. data/lib/active_support/gzip.rb +1 -1
  122. data/lib/active_support/hash_with_indifferent_access.rb +40 -11
  123. data/lib/active_support/i18n_railtie.rb +25 -4
  124. data/lib/active_support/inflector/inflections.rb +36 -5
  125. data/lib/active_support/inflector/methods.rb +97 -90
  126. data/lib/active_support/inflector/transliterate.rb +36 -21
  127. data/lib/active_support/json/decoding.rb +11 -10
  128. data/lib/active_support/json/encoding.rb +1 -51
  129. data/lib/active_support/key_generator.rb +7 -9
  130. data/lib/active_support/lazy_load_hooks.rb +46 -18
  131. data/lib/active_support/locale/en.yml +2 -0
  132. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  133. data/lib/active_support/log_subscriber.rb +1 -1
  134. data/lib/active_support/logger.rb +3 -4
  135. data/lib/active_support/logger_silence.rb +2 -1
  136. data/lib/active_support/logger_thread_safe_level.rb +2 -3
  137. data/lib/active_support/message_encryptor.rb +7 -7
  138. data/lib/active_support/message_verifier.rb +70 -8
  139. data/lib/active_support/multibyte/chars.rb +12 -3
  140. data/lib/active_support/multibyte/unicode.rb +44 -21
  141. data/lib/active_support/notifications/fanout.rb +5 -5
  142. data/lib/active_support/notifications/instrumenter.rb +20 -2
  143. data/lib/active_support/notifications.rb +2 -2
  144. data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
  145. data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
  146. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  147. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
  148. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  149. data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
  150. data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
  151. data/lib/active_support/number_helper.rb +90 -67
  152. data/lib/active_support/ordered_hash.rb +1 -1
  153. data/lib/active_support/ordered_options.rb +15 -1
  154. data/lib/active_support/per_thread_registry.rb +3 -0
  155. data/lib/active_support/rails.rb +2 -2
  156. data/lib/active_support/railtie.rb +6 -1
  157. data/lib/active_support/reloader.rb +129 -0
  158. data/lib/active_support/rescuable.rb +101 -47
  159. data/lib/active_support/string_inquirer.rb +1 -1
  160. data/lib/active_support/subscriber.rb +5 -10
  161. data/lib/active_support/tagged_logging.rb +8 -7
  162. data/lib/active_support/test_case.rb +17 -29
  163. data/lib/active_support/testing/assertions.rb +15 -13
  164. data/lib/active_support/testing/deprecation.rb +9 -8
  165. data/lib/active_support/testing/file_fixtures.rb +34 -0
  166. data/lib/active_support/testing/isolation.rb +22 -8
  167. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  168. data/lib/active_support/testing/stream.rb +42 -0
  169. data/lib/active_support/testing/time_helpers.rb +3 -1
  170. data/lib/active_support/time_with_zone.rb +123 -33
  171. data/lib/active_support/values/time_zone.rb +101 -47
  172. data/lib/active_support/values/unicode_tables.dat +0 -0
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +2 -2
  175. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  176. data/lib/active_support.rb +11 -6
  177. metadata +36 -17
  178. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  179. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  180. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  181. data/lib/active_support/core_ext/object/itself.rb +0 -15
  182. data/lib/active_support/core_ext/thread.rb +0 -86
@@ -1,3 +1,4 @@
1
- Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
1
+ DEPRECATED_FILES = ["#{File.dirname(__FILE__)}/core_ext/struct.rb"]
2
+ (Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"] - DEPRECATED_FILES).each do |path|
2
3
  require path
3
4
  end
@@ -0,0 +1,55 @@
1
+ require 'active_support/concurrency/share_lock'
2
+
3
+ module ActiveSupport #:nodoc:
4
+ module Dependencies #:nodoc:
5
+ class Interlock
6
+ def initialize # :nodoc:
7
+ @lock = ActiveSupport::Concurrency::ShareLock.new
8
+ end
9
+
10
+ def loading
11
+ @lock.exclusive(purpose: :load, compatible: [:load], after_compatible: [:load]) do
12
+ yield
13
+ end
14
+ end
15
+
16
+ def unloading
17
+ @lock.exclusive(purpose: :unload, compatible: [:load, :unload], after_compatible: [:load, :unload]) do
18
+ yield
19
+ end
20
+ end
21
+
22
+ def start_unloading
23
+ @lock.start_exclusive(purpose: :unload, compatible: [:load, :unload])
24
+ end
25
+
26
+ def done_unloading
27
+ @lock.stop_exclusive(compatible: [:load, :unload])
28
+ end
29
+
30
+ def start_running
31
+ @lock.start_sharing
32
+ end
33
+
34
+ def done_running
35
+ @lock.stop_sharing
36
+ end
37
+
38
+ def running
39
+ @lock.sharing do
40
+ yield
41
+ end
42
+ end
43
+
44
+ def permit_concurrent_loads
45
+ @lock.yield_shares(compatible: [:load]) do
46
+ yield
47
+ end
48
+ end
49
+
50
+ def raw_state(&block) # :nodoc:
51
+ @lock.raw_state(&block)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,6 +1,6 @@
1
1
  require 'set'
2
2
  require 'thread'
3
- require 'thread_safe'
3
+ require 'concurrent/map'
4
4
  require 'pathname'
5
5
  require 'active_support/core_ext/module/aliasing'
6
6
  require 'active_support/core_ext/module/attribute_accessors'
@@ -12,12 +12,40 @@ require 'active_support/core_ext/kernel/reporting'
12
12
  require 'active_support/core_ext/load_error'
13
13
  require 'active_support/core_ext/name_error'
14
14
  require 'active_support/core_ext/string/starts_ends_with'
15
+ require "active_support/dependencies/interlock"
15
16
  require 'active_support/inflector'
16
17
 
17
18
  module ActiveSupport #:nodoc:
18
19
  module Dependencies #:nodoc:
19
20
  extend self
20
21
 
22
+ mattr_accessor :interlock
23
+ self.interlock = Interlock.new
24
+
25
+ # :doc:
26
+
27
+ # Execute the supplied block without interference from any
28
+ # concurrent loads.
29
+ def self.run_interlock
30
+ Dependencies.interlock.running { yield }
31
+ end
32
+
33
+ # Execute the supplied block while holding an exclusive lock,
34
+ # preventing any other thread from being inside a #run_interlock
35
+ # block at the same time.
36
+ def self.load_interlock
37
+ Dependencies.interlock.loading { yield }
38
+ end
39
+
40
+ # Execute the supplied block while holding an exclusive lock,
41
+ # preventing any other thread from being inside a #run_interlock
42
+ # block at the same time.
43
+ def self.unload_interlock
44
+ Dependencies.interlock.unloading { yield }
45
+ end
46
+
47
+ # :nodoc:
48
+
21
49
  # Should we turn on Ruby warnings on the first load of dependent files?
22
50
  mattr_accessor :warnings_on_first_load
23
51
  self.warnings_on_first_load = false
@@ -60,15 +88,6 @@ module ActiveSupport #:nodoc:
60
88
  mattr_accessor :explicitly_unloadable_constants
61
89
  self.explicitly_unloadable_constants = []
62
90
 
63
- # The logger is used for generating information on the action run-time
64
- # (including benchmarking) if available. Can be set to nil for no logging.
65
- # Compatible with both Ruby's own Logger and Log4r loggers.
66
- mattr_accessor :logger
67
-
68
- # Set to +true+ to enable logging of const_missing and file loads.
69
- mattr_accessor :log_activity
70
- self.log_activity = false
71
-
72
91
  # The WatchStack keeps a stack of the modules being watched as files are
73
92
  # loaded. If a file in the process of being loaded (parent.rb) triggers the
74
93
  # load of another file (child.rb) the stack will ensure that child.rb
@@ -115,11 +134,11 @@ module ActiveSupport #:nodoc:
115
134
  next unless mod.is_a?(Module)
116
135
 
117
136
  # Get a list of the constants that were added
118
- new_constants = mod.local_constants - original_constants
137
+ new_constants = mod.constants(false) - original_constants
119
138
 
120
- # self[namespace] returns an Array of the constants that are being evaluated
139
+ # @stack[namespace] returns an Array of the constants that are being evaluated
121
140
  # for that namespace. For instance, if parent.rb requires child.rb, the first
122
- # element of self[Object] will be an Array of the constants that were present
141
+ # element of @stack[Object] will be an Array of the constants that were present
123
142
  # before parent.rb was required. The second element will be an Array of the
124
143
  # constants that were present before child.rb was required.
125
144
  @stack[namespace].each do |namespace_constants|
@@ -128,7 +147,7 @@ module ActiveSupport #:nodoc:
128
147
 
129
148
  # Normalize the list of new constants, and add them to the list we will return
130
149
  new_constants.each do |suffix|
131
- constants << ([namespace, suffix] - ["Object"]).join("::")
150
+ constants << ([namespace, suffix] - ["Object"]).join("::".freeze)
132
151
  end
133
152
  end
134
153
  constants
@@ -143,7 +162,7 @@ module ActiveSupport #:nodoc:
143
162
  @watching << namespaces.map do |namespace|
144
163
  module_name = Dependencies.to_constant_name(namespace)
145
164
  original_constants = Dependencies.qualified_const_defined?(module_name) ?
146
- Inflector.constantize(module_name).local_constants : []
165
+ Inflector.constantize(module_name).constants(false) : []
147
166
 
148
167
  @stack[module_name] << original_constants
149
168
  module_name
@@ -234,7 +253,7 @@ module ActiveSupport #:nodoc:
234
253
  end
235
254
 
236
255
  def load_dependency(file)
237
- if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
256
+ if Dependencies.load? && Dependencies.constant_watch_stack.watching?
238
257
  Dependencies.new_constants_in(Object) { yield }
239
258
  else
240
259
  yield
@@ -324,56 +343,58 @@ module ActiveSupport #:nodoc:
324
343
  end
325
344
 
326
345
  def clear
327
- log_call
328
- loaded.clear
329
- loading.clear
330
- remove_unloadable_constants!
346
+ Dependencies.unload_interlock do
347
+ loaded.clear
348
+ loading.clear
349
+ remove_unloadable_constants!
350
+ end
331
351
  end
332
352
 
333
353
  def require_or_load(file_name, const_path = nil)
334
- log_call file_name, const_path
335
354
  file_name = $` if file_name =~ /\.rb\z/
336
355
  expanded = File.expand_path(file_name)
337
356
  return if loaded.include?(expanded)
338
357
 
339
- # Record that we've seen this file *before* loading it to avoid an
340
- # infinite loop with mutual dependencies.
341
- loaded << expanded
342
- loading << expanded
343
-
344
- begin
345
- if load?
346
- log "loading #{file_name}"
358
+ Dependencies.load_interlock do
359
+ # Maybe it got loaded while we were waiting for our lock:
360
+ return if loaded.include?(expanded)
347
361
 
348
- # Enable warnings if this file has not been loaded before and
349
- # warnings_on_first_load is set.
350
- load_args = ["#{file_name}.rb"]
351
- load_args << const_path unless const_path.nil?
362
+ # Record that we've seen this file *before* loading it to avoid an
363
+ # infinite loop with mutual dependencies.
364
+ loaded << expanded
365
+ loading << expanded
352
366
 
353
- if !warnings_on_first_load or history.include?(expanded)
354
- result = load_file(*load_args)
367
+ begin
368
+ if load?
369
+ # Enable warnings if this file has not been loaded before and
370
+ # warnings_on_first_load is set.
371
+ load_args = ["#{file_name}.rb"]
372
+ load_args << const_path unless const_path.nil?
373
+
374
+ if !warnings_on_first_load or history.include?(expanded)
375
+ result = load_file(*load_args)
376
+ else
377
+ enable_warnings { result = load_file(*load_args) }
378
+ end
355
379
  else
356
- enable_warnings { result = load_file(*load_args) }
380
+ result = require file_name
357
381
  end
358
- else
359
- log "requiring #{file_name}"
360
- result = require file_name
382
+ rescue Exception
383
+ loaded.delete expanded
384
+ raise
385
+ ensure
386
+ loading.pop
361
387
  end
362
- rescue Exception
363
- loaded.delete expanded
364
- raise
365
- ensure
366
- loading.pop
367
- end
368
388
 
369
- # Record history *after* loading so first load gets warnings.
370
- history << expanded
371
- result
389
+ # Record history *after* loading so first load gets warnings.
390
+ history << expanded
391
+ result
392
+ end
372
393
  end
373
394
 
374
395
  # Is the provided constant path defined?
375
396
  def qualified_const_defined?(path)
376
- Object.qualified_const_defined?(path.sub(/^::/, ''), false)
397
+ Object.const_defined?(path, false)
377
398
  end
378
399
 
379
400
  # Given +path+, a filesystem path to a ruby file, return an array of
@@ -386,13 +407,13 @@ module ActiveSupport #:nodoc:
386
407
 
387
408
  bases.each do |root|
388
409
  expanded_root = File.expand_path(root)
389
- next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
410
+ next unless expanded_path.start_with?(expanded_root)
390
411
 
391
- nesting = expanded_path[(expanded_root.size)..-1]
392
- nesting = nesting[1..-1] if nesting && nesting[0] == ?/
393
- next if nesting.blank?
412
+ root_size = expanded_root.size
413
+ next if expanded_path[root_size] != ?/.freeze
394
414
 
395
- paths << nesting.camelize
415
+ nesting = expanded_path[(root_size + 1)..-1]
416
+ paths << nesting.camelize unless nesting.blank?
396
417
  end
397
418
 
398
419
  paths.uniq!
@@ -401,7 +422,7 @@ module ActiveSupport #:nodoc:
401
422
 
402
423
  # Search for a file in autoload_paths matching the provided suffix.
403
424
  def search_for_file(path_suffix)
404
- path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
425
+ path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb".freeze)
405
426
 
406
427
  autoload_paths.each do |root|
407
428
  path = File.join(root, path_suffix)
@@ -421,7 +442,7 @@ module ActiveSupport #:nodoc:
421
442
  end
422
443
 
423
444
  def load_once_path?(path)
424
- # to_s works around a ruby1.9 issue where String#starts_with?(Pathname)
445
+ # to_s works around a ruby issue where String#starts_with?(Pathname)
425
446
  # will raise a TypeError: no implicit conversion of Pathname into String
426
447
  autoload_once_paths.any? { |base| path.starts_with? base.to_s }
427
448
  end
@@ -436,6 +457,7 @@ module ActiveSupport #:nodoc:
436
457
  mod = Module.new
437
458
  into.const_set const_name, mod
438
459
  autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
460
+ autoloaded_constants.uniq!
439
461
  mod
440
462
  end
441
463
 
@@ -448,7 +470,6 @@ module ActiveSupport #:nodoc:
448
470
  # set of names that the file at +path+ may define. See
449
471
  # +loadable_constants_for_path+ for more details.
450
472
  def load_file(path, const_paths = loadable_constants_for_path(path))
451
- log_call path, const_paths
452
473
  const_paths = [const_paths].compact unless const_paths.is_a? Array
453
474
  parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object }
454
475
 
@@ -459,7 +480,6 @@ module ActiveSupport #:nodoc:
459
480
 
460
481
  autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
461
482
  autoloaded_constants.uniq!
462
- log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
463
483
  result
464
484
  end
465
485
 
@@ -473,8 +493,6 @@ module ActiveSupport #:nodoc:
473
493
  # it is not possible to load the constant into from_mod, try its parent
474
494
  # module using +const_missing+.
475
495
  def load_missing_constant(from_mod, const_name)
476
- log_call from_mod, const_name
477
-
478
496
  unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
479
497
  raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
480
498
  end
@@ -486,7 +504,7 @@ module ActiveSupport #:nodoc:
486
504
 
487
505
  if file_path
488
506
  expanded = File.expand_path(file_path)
489
- expanded.sub!(/\.rb\z/, '')
507
+ expanded.sub!(/\.rb\z/, ''.freeze)
490
508
 
491
509
  if loading.include?(expanded)
492
510
  raise "Circular dependency detected while autoloading constant #{qualified_name}"
@@ -550,7 +568,7 @@ module ActiveSupport #:nodoc:
550
568
 
551
569
  class ClassCache
552
570
  def initialize
553
- @store = ThreadSafe::Cache.new
571
+ @store = Concurrent::Map.new
554
572
  end
555
573
 
556
574
  def empty?
@@ -607,7 +625,7 @@ module ActiveSupport #:nodoc:
607
625
  def autoloaded?(desc)
608
626
  return false if desc.is_a?(Module) && desc.anonymous?
609
627
  name = to_constant_name desc
610
- return false unless qualified_const_defined? name
628
+ return false unless qualified_const_defined?(name)
611
629
  return autoloaded_constants.include?(name)
612
630
  end
613
631
 
@@ -638,25 +656,20 @@ module ActiveSupport #:nodoc:
638
656
  # exception, any new constants are regarded as being only partially defined
639
657
  # and will be removed immediately.
640
658
  def new_constants_in(*descs)
641
- log_call(*descs)
642
-
643
659
  constant_watch_stack.watch_namespaces(descs)
644
- aborting = true
660
+ success = false
645
661
 
646
662
  begin
647
663
  yield # Now yield to the code that is to define new constants.
648
- aborting = false
664
+ success = true
649
665
  ensure
650
666
  new_constants = constant_watch_stack.new_constants
651
667
 
652
- log "New constants: #{new_constants * ', '}"
653
- return new_constants unless aborting
668
+ return new_constants if success
654
669
 
655
- log "Error during loading, removing partially loaded constants "
656
- new_constants.each { |c| remove_constant(c) }.clear
670
+ # Remove partially loaded constants.
671
+ new_constants.each { |c| remove_constant(c) }
657
672
  end
658
-
659
- []
660
673
  end
661
674
 
662
675
  # Convert the provided const desc to a qualified constant name (as a string).
@@ -703,8 +716,6 @@ module ActiveSupport #:nodoc:
703
716
  parent = constantize(parent_name)
704
717
  end
705
718
 
706
- log "removing constant #{const}"
707
-
708
719
  # In an autoloaded user.rb like this
709
720
  #
710
721
  # autoload :Foo, 'foo'
@@ -725,7 +736,7 @@ module ActiveSupport #:nodoc:
725
736
  begin
726
737
  constantized = parent.const_get(to_remove, false)
727
738
  rescue NameError
728
- log "the constant #{const} is not reachable anymore, skipping"
739
+ # The constant is no longer reachable, just skip it.
729
740
  return
730
741
  else
731
742
  constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
@@ -735,27 +746,9 @@ module ActiveSupport #:nodoc:
735
746
  begin
736
747
  parent.instance_eval { remove_const to_remove }
737
748
  rescue NameError
738
- log "the constant #{const} is not reachable anymore, skipping"
749
+ # The constant is no longer reachable, just skip it.
739
750
  end
740
751
  end
741
-
742
- protected
743
- def log_call(*args)
744
- if log_activity?
745
- arg_str = args.collect { |arg| arg.inspect } * ', '
746
- /in `([a-z_\?\!]+)'/ =~ caller(1).first
747
- selector = $1 || '<unknown>'
748
- log "called #{selector}(#{arg_str})"
749
- end
750
- end
751
-
752
- def log(msg)
753
- logger.debug "Dependencies: #{msg}" if log_activity?
754
- end
755
-
756
- def log_activity?
757
- logger && log_activity
758
- end
759
752
  end
760
753
  end
761
754
 
@@ -1,6 +1,8 @@
1
1
  require "active_support/notifications"
2
2
 
3
3
  module ActiveSupport
4
+ # Raised when <tt>ActiveSupport::Deprecation::Behavior#behavior</tt> is set with <tt>:raise</tt>.
5
+ # You would set <tt>:raise</tt>, as a behaviour to raise errors and proactively report exceptions from deprecations.
4
6
  class DeprecationException < StandardError
5
7
  end
6
8
 
@@ -9,7 +11,7 @@ module ActiveSupport
9
11
  DEFAULT_BEHAVIORS = {
10
12
  raise: ->(message, callstack) {
11
13
  e = DeprecationException.new(message)
12
- e.set_backtrace(callstack)
14
+ e.set_backtrace(callstack.map(&:to_s))
13
15
  raise e
14
16
  },
15
17
 
@@ -38,6 +40,18 @@ module ActiveSupport
38
40
  silence: ->(message, callstack) {},
39
41
  }
40
42
 
43
+ # Behavior module allows to determine how to display deprecation messages.
44
+ # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
45
+ # constant. Available behaviors are:
46
+ #
47
+ # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
48
+ # [+stderr+] Log all deprecation warnings to +$stderr+.
49
+ # [+log+] Log all deprecation warnings to +Rails.logger+.
50
+ # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
51
+ # [+silence+] Do nothing.
52
+ #
53
+ # Setting behaviors only affects deprecations that happen after boot time.
54
+ # For more information you can read the documentation of the +behavior=+ method.
41
55
  module Behavior
42
56
  # Whether to print a backtrace along with the warning.
43
57
  attr_accessor :debug
@@ -6,6 +6,7 @@ module ActiveSupport
6
6
  module InstanceDelegator # :nodoc:
7
7
  def self.included(base)
8
8
  base.extend(ClassMethods)
9
+ base.singleton_class.prepend(OverrideDelegators)
9
10
  base.public_class_method :new
10
11
  end
11
12
 
@@ -19,6 +20,18 @@ module ActiveSupport
19
20
  singleton_class.delegate(method_name, to: :instance)
20
21
  end
21
22
  end
23
+
24
+ module OverrideDelegators # :nodoc:
25
+ def warn(message = nil, callstack = nil)
26
+ callstack ||= caller_locations(2)
27
+ super
28
+ end
29
+
30
+ def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
31
+ caller_backtrace ||= caller_locations(2)
32
+ super
33
+ end
34
+ end
22
35
  end
23
36
  end
24
37
  end
@@ -9,35 +9,61 @@ module ActiveSupport
9
9
  # module Fred
10
10
  # extend self
11
11
  #
12
- # def foo; end
13
- # def bar; end
14
- # def baz; end
12
+ # def aaa; end
13
+ # def bbb; end
14
+ # def ccc; end
15
+ # def ddd; end
16
+ # def eee; end
15
17
  # end
16
18
  #
17
- # ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
18
- # # => [:foo, :bar, :baz]
19
+ # Using the default deprecator:
20
+ # ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')
21
+ # # => [:aaa, :bbb, :ccc]
19
22
  #
20
- # Fred.foo
21
- # # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
23
+ # Fred.aaa
24
+ # # DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 5.1. (called from irb_binding at (irb):10)
25
+ # # => nil
22
26
  #
23
- # Fred.bar
24
- # # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
27
+ # Fred.bbb
28
+ # # DEPRECATION WARNING: bbb is deprecated and will be removed from Rails 5.1 (use zzz instead). (called from irb_binding at (irb):11)
29
+ # # => nil
25
30
  #
26
- # Fred.baz
27
- # # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
31
+ # Fred.ccc
32
+ # # DEPRECATION WARNING: ccc is deprecated and will be removed from Rails 5.1 (use Bar#ccc instead). (called from irb_binding at (irb):12)
33
+ # # => nil
34
+ #
35
+ # Passing in a custom deprecator:
36
+ # custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
37
+ # ActiveSupport::Deprecation.deprecate_methods(Fred, ddd: :zzz, deprecator: custom_deprecator)
38
+ # # => [:ddd]
39
+ #
40
+ # Fred.ddd
41
+ # DEPRECATION WARNING: ddd is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):15)
42
+ # # => nil
43
+ #
44
+ # Using a custom deprecator directly:
45
+ # custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
46
+ # custom_deprecator.deprecate_methods(Fred, eee: :zzz)
47
+ # # => [:eee]
48
+ #
49
+ # Fred.eee
50
+ # DEPRECATION WARNING: eee is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):18)
51
+ # # => nil
28
52
  def deprecate_methods(target_module, *method_names)
29
53
  options = method_names.extract_options!
30
- deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance
54
+ deprecator = options.delete(:deprecator) || self
31
55
  method_names += options.keys
32
56
 
33
- method_names.each do |method_name|
34
- target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
35
- target_module.send(:define_method, "#{target}_with_deprecation#{punctuation}") do |*args, &block|
57
+ mod = Module.new do
58
+ method_names.each do |method_name|
59
+ define_method(method_name) do |*args, &block|
36
60
  deprecator.deprecation_warning(method_name, options[method_name])
37
- send(:"#{target}_without_deprecation#{punctuation}", *args, &block)
61
+ super(*args, &block)
38
62
  end
39
63
  end
40
64
  end
65
+
66
+ target_module.prepend(mod)
41
67
  end
42
68
  end
43
69
  end