Updated README.rdoc again
[feedcatcher.git] / vendor / rails / activesupport / lib / active_support / deprecation.rb
1 require 'yaml'
2
3 module ActiveSupport
4 module Deprecation #:nodoc:
5 mattr_accessor :debug
6 self.debug = false
7
8 # Choose the default warn behavior according to RAILS_ENV.
9 # Ignore deprecation warnings in production.
10 DEFAULT_BEHAVIORS = {
11 'test' => Proc.new { |message, callstack|
12 $stderr.puts(message)
13 $stderr.puts callstack.join("\n ") if debug
14 },
15 'development' => Proc.new { |message, callstack|
16 logger = defined?(Rails) ? Rails.logger : Logger.new($stderr)
17 logger.warn message
18 logger.debug callstack.join("\n ") if debug
19 }
20 }
21
22 class << self
23 def warn(message = nil, callstack = caller)
24 behavior.call(deprecation_message(callstack, message), callstack) if behavior && !silenced?
25 end
26
27 def default_behavior
28 if defined?(RAILS_ENV)
29 DEFAULT_BEHAVIORS[RAILS_ENV.to_s]
30 else
31 DEFAULT_BEHAVIORS['test']
32 end
33 end
34
35 # Have deprecations been silenced?
36 def silenced?
37 @silenced = false unless defined?(@silenced)
38 @silenced
39 end
40
41 # Silence deprecation warnings within the block.
42 def silence
43 old_silenced, @silenced = @silenced, true
44 yield
45 ensure
46 @silenced = old_silenced
47 end
48
49 attr_writer :silenced
50
51
52 private
53 def deprecation_message(callstack, message = nil)
54 message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
55 "DEPRECATION WARNING: #{message}. #{deprecation_caller_message(callstack)}"
56 end
57
58 def deprecation_caller_message(callstack)
59 file, line, method = extract_callstack(callstack)
60 if file
61 if line && method
62 "(called from #{method} at #{file}:#{line})"
63 else
64 "(called from #{file}:#{line})"
65 end
66 end
67 end
68
69 def extract_callstack(callstack)
70 if md = callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
71 md.captures
72 else
73 callstack.first
74 end
75 end
76 end
77
78 # Behavior is a block that takes a message argument.
79 mattr_accessor :behavior
80 self.behavior = default_behavior
81
82 # Warnings are not silenced by default.
83 self.silenced = false
84
85 module ClassMethods #:nodoc:
86 # Declare that a method has been deprecated.
87 def deprecate(*method_names)
88 options = method_names.extract_options!
89 method_names = method_names + options.keys
90 method_names.each do |method_name|
91 alias_method_chain(method_name, :deprecation) do |target, punctuation|
92 class_eval(<<-EOS, __FILE__, __LINE__)
93 def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
94 ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
95 self.class.deprecated_method_warning( # self.class.deprecated_method_warning(
96 :#{method_name}, # :generate_secret,
97 #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
98 caller # caller
99 ) # )
100 #{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_without_deprecation(*args, &block)
101 end # end
102 EOS
103 end
104 end
105 end
106
107 def deprecated_method_warning(method_name, message=nil)
108 warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}"
109 case message
110 when Symbol then "#{warning} (use #{message} instead)"
111 when String then "#{warning} (#{message})"
112 else warning
113 end
114 end
115
116 def deprecation_horizon
117 '2.3'
118 end
119 end
120
121 class DeprecationProxy #:nodoc:
122 silence_warnings do
123 instance_methods.each { |m| undef_method m unless m =~ /^__/ }
124 end
125
126 # Don't give a deprecation warning on inspect since test/unit and error
127 # logs rely on it for diagnostics.
128 def inspect
129 target.inspect
130 end
131
132 private
133 def method_missing(called, *args, &block)
134 warn caller, called, args
135 target.__send__(called, *args, &block)
136 end
137 end
138
139 class DeprecatedObjectProxy < DeprecationProxy
140 def initialize(object, message)
141 @object = object
142 @message = message
143 end
144
145 private
146 def target
147 @object
148 end
149
150 def warn(callstack, called, args)
151 ActiveSupport::Deprecation.warn(@message, callstack)
152 end
153 end
154
155 # Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc.
156 # which emits deprecation warnings on any method call (except +inspect+).
157 class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc:
158 def initialize(instance, method, var = "@#{method}")
159 @instance, @method, @var = instance, method, var
160 end
161
162 private
163 def target
164 @instance.__send__(@method)
165 end
166
167 def warn(callstack, called, args)
168 ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
169 end
170 end
171
172 class DeprecatedConstantProxy < DeprecationProxy #:nodoc:
173 def initialize(old_const, new_const)
174 @old_const = old_const
175 @new_const = new_const
176 end
177
178 def class
179 target.class
180 end
181
182 private
183 def target
184 @new_const.to_s.constantize
185 end
186
187 def warn(callstack, called, args)
188 ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
189 end
190 end
191 end
192 end
193
194 class Module
195 include ActiveSupport::Deprecation::ClassMethods
196 end