Method
類別公用方法
included(base) 連結
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 6 def self.included(base) require "active_support/inflector/methods" extension = Module.new do def const_missing(missing_const_name) if class_variable_defined?(:@@_deprecated_constants) if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations) return ActiveSupport::Inflector.constantize(replacement[:new].to_s) end end super end # 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, references to <tt>A::B</tt> still work, they # evaluate to <tt>C::D</tt> now, and trigger a deprecation warning: # # 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_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator } end end base.singleton_class.prepend extension end
物件實體公用方法
const_missing(missing_const_name) 連結
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 10 def const_missing(missing_const_name) if class_variable_defined?(:@@_deprecated_constants) if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations) return ActiveSupport::Inflector.constantize(replacement[:new].to_s) end end super end
deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil) 連結
提供一種方式,以非建議循環來重新命名常數,舊名稱與新名稱皆可使用,但使用舊名稱時會列印出非建議訊息。
如要將 A::B
重新命名為 C::D
,您需要刪除 A::B
的定義,並在 A
中宣告非建議用名稱
require "active_support/deprecation"
module A
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
end
第一個引數是常數名稱(沒有冒號)。為要用於封閉類別或模組的非建議用名稱。
第二個引數是替換項的常數路徑。即使替換項定義在與非建議用名稱相同的命名空間中,此項也必須是完整路徑。
這兩個情況都支援字串和符號。
deprecator
keyword 引數是會列印非建議訊息的物件,一個 ActiveSupport::Deprecation
的實例。
這樣一來,參照 A::B
仍然有用,它們現在等於 C::D
,並觸發非建議警告
DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
(called from ...)
訊息可用選用的 message
keyword 引數自訂。
要達成此目的,會安裝一個 const_missing
hook。當用戶端程式參照已非建議使用的常數時,callback 會列印訊息並將替換項常數化。
要點:如果非建議用常數名稱可在不同的命名空間中存取,且 Ruby 常數查詢找到它,則不會呼叫 hook,非建議用法也無法按預期運作。這可能會發生在一個情況中,例如封閉命名空間的祖先有個名稱相同的常數。這是一個不受支援的特殊情況。
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 65 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_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator } end