File: active_support/deprecation.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: <Built-in Module>
  module: ActiveSupport#3
  module: Deprecation#4
has properties
constant: DEFAULT_BEHAVIORS #10
module method: warn / 2 #23
module method: default_behavior #27
module method: silenced? #36
module method: silence #42
module attribute: silenced [W] #49
module method: deprecation_message / 2 #53
module method: deprecation_caller_message / 1 #59
module method: extract_callstack / 1 #70
  module: ClassMethods#86
has properties
method: deprecate / 1 #88
method: deprecated_method_warning / 2 #108
method: deprecation_horizon #117
  class: DeprecationProxy#122
inherits from
  Object ( Builtin-Module )
has properties
class method: new / 2 #123
method: inspect #136
method: method_missing / 3 #141
  class: DeprecatedObjectProxy#147
inherits from
  DeprecationProxy ( ActiveSupport::Deprecation )
has properties
method: initialize / 2 #148
method: target #154
method: warn / 3 #158
  class: DeprecatedInstanceVariableProxy#165
inherits from
  DeprecationProxy ( ActiveSupport::Deprecation )
has properties
method: initialize / 3 #166
method: target #171
method: warn / 3 #175
  class: DeprecatedConstantProxy#180
inherits from
  DeprecationProxy ( ActiveSupport::Deprecation )
has properties
method: initialize / 2 #181
method: class #186
method: target #191
method: warn / 3 #195

Code

   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) ? 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            message += '.' unless message =~ /\.$/
  56            "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
  57          end
  58 
  59          def deprecation_caller_message(callstack)
  60            file, line, method = extract_callstack(callstack)
  61            if file
  62              if line && method
  63                "(called from #{method} at #{file}:#{line})"
  64              else
  65                "(called from #{file}:#{line})"
  66              end
  67            end
  68          end
  69 
  70          def extract_callstack(callstack)
  71            if md = callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
  72              md.captures
  73            else
  74              callstack.first
  75            end
  76          end
  77      end
  78 
  79      # Behavior is a block that takes a message argument.
  80      mattr_accessor :behavior
  81      self.behavior = default_behavior
  82 
  83      # Warnings are not silenced by default.
  84      self.silenced = false
  85 
  86      module ClassMethods #:nodoc:
  87        # Declare that a method has been deprecated.
  88        def deprecate(*method_names)
  89          options = method_names.extract_options!
  90          method_names = method_names + options.keys
  91          method_names.each do |method_name|
  92            alias_method_chain(method_name, :deprecation) do |target, punctuation|
  93              class_eval(<<-EOS, __FILE__, __LINE__ + 1)
  94                def #{target}_with_deprecation#{punctuation}(*args, &block)          # def generate_secret_with_deprecation(*args, &block)
  95                  ::ActiveSupport::Deprecation.warn(                                 #   ::ActiveSupport::Deprecation.warn(
  96                    self.class.deprecated_method_warning(                            #     self.class.deprecated_method_warning(
  97                      :#{method_name},                                               #       :generate_secret,
  98                      #{options[method_name].inspect}),                              #       "You should use ActiveSupport::SecureRandom.hex(64)"),
  99                    caller                                                           #     caller
 100                  )                                                                  #   )
 101                  send(:#{target}_without_deprecation#{punctuation}, *args, &block)  #   send(:generate_secret_without_deprecation, *args, &block)
 102                end                                                                  # end
 103              EOS
 104            end
 105          end
 106        end
 107 
 108        def deprecated_method_warning(method_name, message=nil)
 109          warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}"
 110          case message
 111            when Symbol then "#{warning} (use #{message} instead)"
 112            when String then "#{warning} (#{message})"
 113            else warning
 114          end
 115        end
 116 
 117        def deprecation_horizon
 118          '2.3'
 119        end
 120      end
 121 
 122      class DeprecationProxy #:nodoc:
 123        def self.new(*args, &block)
 124          object = args.first
 125          
 126          return object unless object
 127          super
 128        end
 129        
 130        silence_warnings do
 131          instance_methods.each { |m| undef_method m unless m =~ /^__/ }
 132        end
 133 
 134        # Don't give a deprecation warning on inspect since test/unit and error
 135        # logs rely on it for diagnostics.
 136        def inspect
 137          target.inspect
 138        end
 139 
 140        private
 141          def method_missing(called, *args, &block)
 142            warn caller, called, args
 143            target.__send__(called, *args, &block)
 144          end
 145      end
 146 
 147      class DeprecatedObjectProxy < DeprecationProxy
 148        def initialize(object, message)
 149          @object = object
 150          @message = message
 151        end
 152 
 153        private
 154          def target
 155            @object
 156          end
 157 
 158          def warn(callstack, called, args)
 159            ActiveSupport::Deprecation.warn(@message, callstack)
 160          end
 161      end
 162 
 163      # Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc.
 164      # which emits deprecation warnings on any method call (except +inspect+).
 165      class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc:
 166        def initialize(instance, method, var = "@#{method}")
 167          @instance, @method, @var = instance, method, var
 168        end
 169 
 170        private
 171          def target
 172            @instance.__send__(@method)
 173          end
 174 
 175          def warn(callstack, called, args)
 176            ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
 177          end
 178      end
 179 
 180      class DeprecatedConstantProxy < DeprecationProxy #:nodoc:
 181        def initialize(old_const, new_const)
 182          @old_const = old_const
 183          @new_const = new_const
 184        end
 185 
 186        def class
 187          target.class
 188        end
 189 
 190        private
 191          def target
 192            @new_const.to_s.constantize
 193          end
 194 
 195          def warn(callstack, called, args)
 196            ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
 197          end
 198      end
 199    end
 200  end
 201 
 202  class Module
 203    include ActiveSupport::Deprecation::ClassMethods
 204  end