Improvements to deprecate_constant
This commit is contained in:
parent
e1f8909c66
commit
cb0acdae88
@ -2,28 +2,6 @@
|
|||||||
|
|
||||||
module ActiveSupport
|
module ActiveSupport
|
||||||
class Deprecation
|
class Deprecation
|
||||||
# DeprecatedConstantAccessor transforms a constant into a deprecated one by
|
|
||||||
# hooking +const_missing+.
|
|
||||||
#
|
|
||||||
# It takes the names of an old (deprecated) constant and of a new constant
|
|
||||||
# (both in string form) and a deprecator.
|
|
||||||
#
|
|
||||||
# The deprecated constant now returns the same object as the new one rather
|
|
||||||
# than a proxy object, so it can be used transparently in +rescue+ blocks
|
|
||||||
# etc.
|
|
||||||
#
|
|
||||||
# PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
|
|
||||||
#
|
|
||||||
# # (In a later update, the original implementation of `PLANETS` has been removed.)
|
|
||||||
#
|
|
||||||
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
|
|
||||||
# include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
|
||||||
# deprecate_constant 'PLANETS', 'PLANETS_POST_2006', deprecator: ActiveSupport::Deprecation.new
|
|
||||||
#
|
|
||||||
# PLANETS.map { |planet| planet.capitalize }
|
|
||||||
# # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
|
|
||||||
# (Backtrace information…)
|
|
||||||
# ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
|
|
||||||
module DeprecatedConstantAccessor
|
module DeprecatedConstantAccessor
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
require "active_support/inflector/methods"
|
require "active_support/inflector/methods"
|
||||||
@ -39,9 +17,53 @@ def const_missing(missing_const_name)
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def deprecate_constant(const_name, new_constant, deprecator:, message: nil)
|
# Provides a way to rename constants with a deprecation cycle in which
|
||||||
|
# both the old and new names work, but using the old one prints a
|
||||||
|
# deprecation message.
|
||||||
|
#
|
||||||
|
# In order to rename <tt>A::B</tt> to <tt>C::D</tt>, you need to delete the
|
||||||
|
# definition of <tt>A::B</tt> and declare the deprecation in +A+:
|
||||||
|
#
|
||||||
|
# require "active_support/deprecation"
|
||||||
|
#
|
||||||
|
# module A
|
||||||
|
# include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
||||||
|
#
|
||||||
|
# deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# The first argument is a constant name (no colons). It is the name of
|
||||||
|
# the constant you want to deprecate in the enclosing class or module.
|
||||||
|
#
|
||||||
|
# The second argument is the constant path of the replacement. That
|
||||||
|
# has to be a full path even if the replacement is defined in the same
|
||||||
|
# namespace as the deprecated one was.
|
||||||
|
#
|
||||||
|
# In both cases, strings and symbols are supported.
|
||||||
|
#
|
||||||
|
# The +deprecator+ keyword argument is the object that will print the
|
||||||
|
# deprecation message, an instance of ActiveSupport::Deprecation.
|
||||||
|
#
|
||||||
|
# With that in place, client code referencing <tt>A::B</tt> will see
|
||||||
|
#
|
||||||
|
# DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
|
||||||
|
# (called from ...)
|
||||||
|
#
|
||||||
|
# The message can be customized with the optional +message+ keyword
|
||||||
|
# argument.
|
||||||
|
#
|
||||||
|
# For this to work, a +const_missing+ hook is installed. When client
|
||||||
|
# code references the deprecated constant, the callback prints the
|
||||||
|
# message and constantizes the replacement.
|
||||||
|
#
|
||||||
|
# Caveat: If the deprecated constant name is reachable in a different
|
||||||
|
# namespace and Ruby constant lookup finds it, the hook won't be
|
||||||
|
# called and the deprecation won't work as intended. This may happen,
|
||||||
|
# for example, if an ancestor of the enclosing namespace has a
|
||||||
|
# constant with the same name. This is an unsupported edge case.
|
||||||
|
def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil)
|
||||||
class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
|
class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
|
||||||
class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator }
|
class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
base.singleton_class.prepend extension
|
base.singleton_class.prepend extension
|
||||||
|
Loading…
Reference in New Issue
Block a user