activesupport 4.2.11.3 → 5.0.0.beta1

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 (174) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +309 -485
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/active_support.rb +8 -15
  6. data/lib/active_support/array_inquirer.rb +44 -0
  7. data/lib/active_support/backtrace_cleaner.rb +1 -1
  8. data/lib/active_support/cache.rb +59 -72
  9. data/lib/active_support/cache/file_store.rb +27 -19
  10. data/lib/active_support/cache/mem_cache_store.rb +71 -60
  11. data/lib/active_support/cache/memory_store.rb +16 -21
  12. data/lib/active_support/cache/null_store.rb +1 -4
  13. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  14. data/lib/active_support/callbacks.rb +107 -111
  15. data/lib/active_support/concern.rb +1 -1
  16. data/lib/active_support/concurrency/latch.rb +7 -15
  17. data/lib/active_support/concurrency/share_lock.rb +142 -0
  18. data/lib/active_support/configurable.rb +1 -0
  19. data/lib/active_support/core_ext.rb +2 -1
  20. data/lib/active_support/core_ext/array.rb +1 -0
  21. data/lib/active_support/core_ext/array/access.rb +13 -1
  22. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  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/big_decimal/conversions.rb +8 -10
  26. data/lib/active_support/core_ext/class.rb +0 -1
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +5 -2
  29. data/lib/active_support/core_ext/date.rb +1 -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 +3 -3
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
  34. data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
  35. data/lib/active_support/core_ext/date_time.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  37. data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
  38. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  39. data/lib/active_support/core_ext/enumerable.rb +27 -17
  40. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  41. data/lib/active_support/core_ext/hash/compact.rb +15 -19
  42. data/lib/active_support/core_ext/hash/conversions.rb +21 -2
  43. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  44. data/lib/active_support/core_ext/hash/except.rb +9 -8
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  46. data/lib/active_support/core_ext/hash/keys.rb +22 -18
  47. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  48. data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
  49. data/lib/active_support/core_ext/integer/time.rb +1 -1
  50. data/lib/active_support/core_ext/kernel.rb +0 -1
  51. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  52. data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
  53. data/lib/active_support/core_ext/load_error.rb +4 -2
  54. data/lib/active_support/core_ext/marshal.rb +8 -13
  55. data/lib/active_support/core_ext/module.rb +1 -0
  56. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  57. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
  60. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  61. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  62. data/lib/active_support/core_ext/module/delegation.rb +7 -14
  63. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  64. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  65. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  66. data/lib/active_support/core_ext/name_error.rb +15 -2
  67. data/lib/active_support/core_ext/numeric.rb +1 -0
  68. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  69. data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
  70. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  71. data/lib/active_support/core_ext/numeric/time.rb +20 -0
  72. data/lib/active_support/core_ext/object.rb +0 -1
  73. data/lib/active_support/core_ext/object/blank.rb +11 -2
  74. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  75. data/lib/active_support/core_ext/object/duplicable.rb +39 -70
  76. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  77. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  78. data/lib/active_support/core_ext/object/json.rb +9 -7
  79. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  80. data/lib/active_support/core_ext/object/try.rb +67 -21
  81. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  82. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  83. data/lib/active_support/core_ext/range/each.rb +16 -18
  84. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  85. data/lib/active_support/core_ext/securerandom.rb +23 -0
  86. data/lib/active_support/core_ext/string/access.rb +1 -1
  87. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  88. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  89. data/lib/active_support/core_ext/string/filters.rb +1 -2
  90. data/lib/active_support/core_ext/string/inflections.rb +23 -5
  91. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  92. data/lib/active_support/core_ext/string/output_safety.rb +8 -9
  93. data/lib/active_support/core_ext/string/strip.rb +3 -6
  94. data/lib/active_support/core_ext/struct.rb +3 -6
  95. data/lib/active_support/core_ext/time.rb +0 -2
  96. data/lib/active_support/core_ext/time/calculations.rb +18 -16
  97. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  98. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  99. data/lib/active_support/core_ext/time/zones.rb +19 -3
  100. data/lib/active_support/core_ext/uri.rb +1 -3
  101. data/lib/active_support/dependencies.rb +79 -44
  102. data/lib/active_support/dependencies/interlock.rb +47 -0
  103. data/lib/active_support/deprecation/behaviors.rb +12 -0
  104. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  105. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  106. data/lib/active_support/deprecation/reporting.rb +13 -2
  107. data/lib/active_support/duration.rb +5 -8
  108. data/lib/active_support/evented_file_update_checker.rb +150 -0
  109. data/lib/active_support/file_update_checker.rb +1 -1
  110. data/lib/active_support/gem_version.rb +5 -5
  111. data/lib/active_support/hash_with_indifferent_access.rb +15 -17
  112. data/lib/active_support/i18n_railtie.rb +25 -4
  113. data/lib/active_support/inflector/inflections.rb +36 -5
  114. data/lib/active_support/inflector/methods.rb +87 -89
  115. data/lib/active_support/inflector/transliterate.rb +36 -21
  116. data/lib/active_support/json/decoding.rb +2 -8
  117. data/lib/active_support/json/encoding.rb +0 -50
  118. data/lib/active_support/key_generator.rb +4 -4
  119. data/lib/active_support/log_subscriber.rb +1 -1
  120. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  121. data/lib/active_support/logger.rb +4 -52
  122. data/lib/active_support/logger_silence.rb +3 -5
  123. data/lib/active_support/message_encryptor.rb +4 -11
  124. data/lib/active_support/message_verifier.rb +64 -8
  125. data/lib/active_support/multibyte/chars.rb +12 -3
  126. data/lib/active_support/multibyte/unicode.rb +6 -8
  127. data/lib/active_support/notifications.rb +2 -2
  128. data/lib/active_support/notifications/fanout.rb +5 -5
  129. data/lib/active_support/notifications/instrumenter.rb +19 -2
  130. data/lib/active_support/number_helper.rb +21 -15
  131. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
  132. data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
  133. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  134. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
  135. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  136. data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
  137. data/lib/active_support/ordered_options.rb +15 -1
  138. data/lib/active_support/per_thread_registry.rb +3 -0
  139. data/lib/active_support/rails.rb +2 -2
  140. data/lib/active_support/railtie.rb +6 -1
  141. data/lib/active_support/rescuable.rb +4 -4
  142. data/lib/active_support/security_utils.rb +0 -7
  143. data/lib/active_support/string_inquirer.rb +1 -1
  144. data/lib/active_support/subscriber.rb +5 -10
  145. data/lib/active_support/tagged_logging.rb +3 -1
  146. data/lib/active_support/test_case.rb +13 -25
  147. data/lib/active_support/testing/assertions.rb +15 -13
  148. data/lib/active_support/testing/autorun.rb +8 -1
  149. data/lib/active_support/testing/composite_filter.rb +54 -0
  150. data/lib/active_support/testing/deprecation.rb +9 -8
  151. data/lib/active_support/testing/file_fixtures.rb +34 -0
  152. data/lib/active_support/testing/isolation.rb +22 -8
  153. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  154. data/lib/active_support/testing/stream.rb +42 -0
  155. data/lib/active_support/testing/time_helpers.rb +6 -6
  156. data/lib/active_support/time_with_zone.rb +135 -53
  157. data/lib/active_support/values/time_zone.rb +80 -46
  158. data/lib/active_support/values/unicode_tables.dat +0 -0
  159. data/lib/active_support/xml_mini.rb +15 -30
  160. data/lib/active_support/xml_mini/jdom.rb +1 -1
  161. data/lib/active_support/xml_mini/libxml.rb +5 -3
  162. data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
  163. data/lib/active_support/xml_mini/nokogiri.rb +5 -3
  164. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  165. data/lib/active_support/xml_mini/rexml.rb +3 -1
  166. metadata +57 -21
  167. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  168. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  169. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
  170. data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
  171. data/lib/active_support/core_ext/object/itself.rb +0 -15
  172. data/lib/active_support/core_ext/thread.rb +0 -86
  173. data/lib/active_support/core_ext/time/compatibility.rb +0 -14
  174. data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -0,0 +1,47 @@
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]) do
12
+ yield
13
+ end
14
+ end
15
+
16
+ def unloading
17
+ @lock.exclusive(purpose: :unload, compatible: [:load, :unload]) do
18
+ yield
19
+ end
20
+ end
21
+
22
+ # Attempt to obtain an "unloading" (exclusive) lock. If possible,
23
+ # execute the supplied block while holding the lock. If there is
24
+ # concurrent activity, return immediately (without executing the
25
+ # block) instead of waiting.
26
+ def attempt_unloading
27
+ @lock.exclusive(purpose: :unload, compatible: [:load, :unload], no_wait: true) do
28
+ yield
29
+ end
30
+ end
31
+
32
+ def start_running
33
+ @lock.start_sharing
34
+ end
35
+
36
+ def done_running
37
+ @lock.stop_sharing
38
+ end
39
+
40
+ def running
41
+ @lock.sharing do
42
+ yield
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -38,6 +38,18 @@ module ActiveSupport
38
38
  silence: ->(message, callstack) {},
39
39
  }
40
40
 
41
+ # Behavior module allows to determine how to display deprecation messages.
42
+ # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
43
+ # constant. Available behaviors are:
44
+ #
45
+ # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
46
+ # [+stderr+] Log all deprecation warnings to +$stderr+.
47
+ # [+log+] Log all deprecation warnings to +Rails.logger+.
48
+ # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
49
+ # [+silence+] Do nothing.
50
+ #
51
+ # Setting behaviors only affects deprecations that happen after boot time.
52
+ # For more information you can read the documentation of the +behavior=+ method.
41
53
  module Behavior
42
54
  # Whether to print a backtrace along with the warning.
43
55
  attr_accessor :debug
@@ -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.0. (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.0 (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.0 (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
@@ -20,20 +20,22 @@ module ActiveSupport
20
20
 
21
21
  private
22
22
  def method_missing(called, *args, &block)
23
- warn caller, called, args
23
+ warn caller_locations, called, args
24
24
  target.__send__(called, *args, &block)
25
25
  end
26
26
  end
27
27
 
28
- # This DeprecatedObjectProxy transforms object to deprecated object.
28
+ # DeprecatedObjectProxy transforms an object into a deprecated one. It
29
+ # takes an object, a deprecation message and optionally a deprecator. The
30
+ # deprecator defaults to +ActiveSupport::Deprecator+ if none is specified.
29
31
  #
30
- # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!")
31
- # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance)
32
+ # deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated")
33
+ # # => #<Object:0x007fb9b34c34b0>
32
34
  #
33
- # When someone executes any method except +inspect+ on proxy object this will
34
- # trigger +warn+ method on +deprecator_instance+.
35
- #
36
- # Default deprecator is <tt>ActiveSupport::Deprecation</tt>
35
+ # deprecated_object.to_s
36
+ # DEPRECATION WARNING: This object is now deprecated.
37
+ # (Backtrace)
38
+ # # => "#<Object:0x007fb9b34c34b0>"
37
39
  class DeprecatedObjectProxy < DeprecationProxy
38
40
  def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance)
39
41
  @object = object
@@ -51,13 +53,16 @@ module ActiveSupport
51
53
  end
52
54
  end
53
55
 
54
- # This DeprecatedInstanceVariableProxy transforms instance variable to
55
- # deprecated instance variable.
56
+ # DeprecatedInstanceVariableProxy transforms an instance variable into a
57
+ # deprecated one. It takes an instance of a class, a method on that class
58
+ # and an instance variable. It optionally takes a deprecator as the last
59
+ # argument. The deprecator defaults to +ActiveSupport::Deprecator+ if none
60
+ # is specified.
56
61
  #
57
62
  # class Example
58
- # def initialize(deprecator)
59
- # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
60
- # @_request = :a_request
63
+ # def initialize
64
+ # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request)
65
+ # @_request = :special_request
61
66
  # end
62
67
  #
63
68
  # def request
@@ -69,12 +74,17 @@ module ActiveSupport
69
74
  # end
70
75
  # end
71
76
  #
72
- # When someone execute any method on @request variable this will trigger
73
- # +warn+ method on +deprecator_instance+ and will fetch <tt>@_request</tt>
74
- # variable via +request+ method and execute the same method on non-proxy
75
- # instance variable.
77
+ # example = Example.new
78
+ # # => #<Example:0x007fb9b31090b8 @_request=:special_request, @request=:special_request>
79
+ #
80
+ # example.old_request.to_s
81
+ # # => DEPRECATION WARNING: @request is deprecated! Call request.to_s instead of
82
+ # @request.to_s
83
+ # (Bactrace information…)
84
+ # "special_request"
76
85
  #
77
- # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
86
+ # example.request.to_s
87
+ # # => "special_request"
78
88
  class DeprecatedInstanceVariableProxy < DeprecationProxy
79
89
  def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance)
80
90
  @instance = instance
@@ -93,15 +103,23 @@ module ActiveSupport
93
103
  end
94
104
  end
95
105
 
96
- # This DeprecatedConstantProxy transforms constant to deprecated constant.
106
+ # DeprecatedConstantProxy transforms a constant into a deprecated one. It
107
+ # takes the names of an old (deprecated) constant and of a new constant
108
+ # (both in string form) and optionally a deprecator. The deprecator defaults
109
+ # to +ActiveSupport::Deprecator+ if none is specified. The deprecated constant
110
+ # now returns the value of the new one.
111
+ #
112
+ # PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
97
113
  #
98
- # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST')
99
- # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance)
114
+ # (In a later update, the original implementation of `PLANETS` has been removed.)
100
115
  #
101
- # When someone use old constant this will trigger +warn+ method on
102
- # +deprecator_instance+.
116
+ # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
117
+ # PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
103
118
  #
104
- # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
119
+ # PLANETS.map { |planet| planet.capitalize }
120
+ # # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
121
+ # (Bactrace information…)
122
+ # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
105
123
  class DeprecatedConstantProxy < DeprecationProxy
106
124
  def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance)
107
125
  @old_const = old_const
@@ -109,6 +127,11 @@ module ActiveSupport
109
127
  @deprecator = deprecator
110
128
  end
111
129
 
130
+ # Returns the class of the new constant.
131
+ #
132
+ # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
133
+ # PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
134
+ # PLANETS.class # => Array
112
135
  def class
113
136
  target.class
114
137
  end
@@ -14,7 +14,7 @@ module ActiveSupport
14
14
  def warn(message = nil, callstack = nil)
15
15
  return if silenced
16
16
 
17
- callstack ||= caller(2)
17
+ callstack ||= caller_locations(2)
18
18
  deprecation_message(callstack, message).tap do |m|
19
19
  behavior.each { |b| b.call(m, callstack) }
20
20
  end
@@ -37,7 +37,7 @@ module ActiveSupport
37
37
  end
38
38
 
39
39
  def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
40
- caller_backtrace ||= caller(2)
40
+ caller_backtrace ||= caller_locations(2)
41
41
  deprecated_method_warning(deprecated_method_name, message).tap do |msg|
42
42
  warn(msg, caller_backtrace)
43
43
  end
@@ -79,6 +79,17 @@ module ActiveSupport
79
79
  end
80
80
 
81
81
  def extract_callstack(callstack)
82
+ return _extract_callstack(callstack) if callstack.first.is_a? String
83
+
84
+ rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
85
+ offending_line = callstack.find { |frame|
86
+ frame.absolute_path && !frame.absolute_path.start_with?(rails_gem_root)
87
+ } || callstack.first
88
+ [offending_line.path, offending_line.lineno, offending_line.label]
89
+ end
90
+
91
+ def _extract_callstack(callstack)
92
+ warn "Please pass `caller_locations` to the deprecation API" if $VERBOSE
82
93
  rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
83
94
  offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first
84
95
  if offending_line
@@ -52,6 +52,10 @@ module ActiveSupport
52
52
  end
53
53
  end
54
54
 
55
+ # Returns the amount of seconds a duration covers as a string.
56
+ # For more information check to_i method.
57
+ #
58
+ # 1.day.to_s # => "86400"
55
59
  def to_s
56
60
  @value.to_s
57
61
  end
@@ -122,7 +126,7 @@ module ActiveSupport
122
126
  to_i
123
127
  end
124
128
 
125
- def respond_to_missing?(method, include_private=false) #:nodoc
129
+ def respond_to_missing?(method, include_private=false) #:nodoc:
126
130
  @value.respond_to?(method, include_private)
127
131
  end
128
132
 
@@ -146,13 +150,6 @@ module ActiveSupport
146
150
 
147
151
  private
148
152
 
149
- # We define it as a workaround to Ruby 2.0.0-p353 bug.
150
- # For more information, check rails/rails#13055.
151
- # Remove it when we drop support for 2.0.0-p353.
152
- def ===(other) #:nodoc:
153
- value === other
154
- end
155
-
156
153
  def method_missing(method, *args, &block) #:nodoc:
157
154
  value.send(method, *args, &block)
158
155
  end
@@ -0,0 +1,150 @@
1
+ require 'set'
2
+ require 'pathname'
3
+ require 'concurrent/atomic/atomic_boolean'
4
+
5
+ module ActiveSupport
6
+ class EventedFileUpdateChecker #:nodoc: all
7
+ def initialize(files, dirs = {}, &block)
8
+ @ph = PathHelper.new
9
+ @files = files.map { |f| @ph.xpath(f) }.to_set
10
+
11
+ @dirs = {}
12
+ dirs.each do |dir, exts|
13
+ @dirs[@ph.xpath(dir)] = Array(exts).map { |ext| @ph.normalize_extension(ext) }
14
+ end
15
+
16
+ @block = block
17
+ @updated = Concurrent::AtomicBoolean.new(false)
18
+ @lcsp = @ph.longest_common_subpath(@dirs.keys)
19
+
20
+ if (dtw = directories_to_watch).any?
21
+ # Loading listen triggers warnings. These are originated by a legit
22
+ # usage of attr_* macros for private attributes, but adds a lot of noise
23
+ # to our test suite. Thus, we lazy load it and disable warnings locally.
24
+ silence_warnings { require 'listen' }
25
+ Listen.to(*dtw, &method(:changed)).start
26
+ end
27
+ end
28
+
29
+ def updated?
30
+ @updated.true?
31
+ end
32
+
33
+ def execute
34
+ @updated.make_false
35
+ @block.call
36
+ end
37
+
38
+ def execute_if_updated
39
+ if updated?
40
+ execute
41
+ true
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def changed(modified, added, removed)
48
+ unless updated?
49
+ @updated.make_true if (modified + added + removed).any? { |f| watching?(f) }
50
+ end
51
+ end
52
+
53
+ def watching?(file)
54
+ file = @ph.xpath(file)
55
+
56
+ if @files.member?(file)
57
+ true
58
+ elsif file.directory?
59
+ false
60
+ else
61
+ ext = @ph.normalize_extension(file.extname)
62
+
63
+ file.dirname.ascend do |dir|
64
+ if @dirs.fetch(dir, []).include?(ext)
65
+ break true
66
+ elsif dir == @lcsp || dir.root?
67
+ break false
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def directories_to_watch
74
+ dtw = (@files + @dirs.keys).map { |f| @ph.existing_parent(f) }
75
+ dtw.compact!
76
+ dtw.uniq!
77
+
78
+ @ph.filter_out_descendants(dtw)
79
+ end
80
+
81
+ class PathHelper
82
+ using Module.new {
83
+ refine Pathname do
84
+ def ascendant_of?(other)
85
+ self != other && other.ascend do |ascendant|
86
+ break true if self == ascendant
87
+ end
88
+ end
89
+ end
90
+ }
91
+
92
+ def xpath(path)
93
+ Pathname.new(path).expand_path
94
+ end
95
+
96
+ def normalize_extension(ext)
97
+ ext.to_s.sub(/\A\./, '')
98
+ end
99
+
100
+ # Given a collection of Pathname objects returns the longest subpath
101
+ # common to all of them, or +nil+ if there is none.
102
+ def longest_common_subpath(paths)
103
+ return if paths.empty?
104
+
105
+ lcsp = Pathname.new(paths[0])
106
+
107
+ paths[1..-1].each do |path|
108
+ until lcsp.ascendant_of?(path)
109
+ if lcsp.root?
110
+ # If we get here a root directory is not an ascendant of path.
111
+ # This may happen if there are paths in different drives on
112
+ # Windows.
113
+ return
114
+ else
115
+ lcsp = lcsp.parent
116
+ end
117
+ end
118
+ end
119
+
120
+ lcsp
121
+ end
122
+
123
+ # Returns the deepest existing ascendant, which could be the argument itself.
124
+ def existing_parent(dir)
125
+ dir.ascend do |ascendant|
126
+ break ascendant if ascendant.directory?
127
+ end
128
+ end
129
+
130
+ # Filters out directories which are descendants of others in the collection (stable).
131
+ def filter_out_descendants(dirs)
132
+ return dirs if dirs.length < 2
133
+
134
+ dirs_sorted_by_nparts = dirs.sort_by { |dir| dir.each_filename.to_a.length }
135
+ descendants = []
136
+
137
+ until dirs_sorted_by_nparts.empty?
138
+ dir = dirs_sorted_by_nparts.shift
139
+
140
+ dirs_sorted_by_nparts.reject! do |possible_descendant|
141
+ dir.ascendant_of?(possible_descendant) && descendants << possible_descendant
142
+ end
143
+ end
144
+
145
+ # Array#- preserves order.
146
+ dirs - descendants
147
+ end
148
+ end
149
+ end
150
+ end