如何重构已弃用的代码 alias_method_chain
How to refactor code for deprecated alias_method_chain
我正在升级我的 rails 应用程序,我收到一条警告说 alias_method_chain is deprecated. Please, use Module#prepend instead
。但我真的不明白如何处理这个。我怎样才能更改下面的代码?
def read_attribute_with_mapping(attr_name)
read_attribute_without_mapping(ADDRESS_MAPPING[attr_name] || attr_name)
end
alias_method_chain :read_attribute, :mapping
prepend
基本上就像导入一个模块,但它以 "in front" 其他代码结束(因此模块可以调用 super
到 运行 它所在的代码前面)。
这是一个运行可行的例子,与您的情况很接近。
module MyModule
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
class Example
prepend MyModule
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
我直接在Example
上定义了read_attribute
,但它也可以是从超类(例如ActiveRecord::Base
)继承的方法。
这是一个使用匿名模块的更短但更神秘的版本:
class Example
prepend(Module.new do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end)
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
更新:
只是为了好玩和解决下面的问题,下面是如何在不必自己明确制作任何模块的情况下完成的。我不认为我会选择自己这样做,因为它掩盖了一个共同的模式。
# You'd do this once somewhere, e.g. config/initializers/prepend_block.rb in a Rails app.
class Module
def prepend_block(&block)
prepend Module.new.tap { |m| m.module_eval(&block) }
end
end
# Now you can do:
class Example
prepend_block do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
我正在升级我的 rails 应用程序,我收到一条警告说 alias_method_chain is deprecated. Please, use Module#prepend instead
。但我真的不明白如何处理这个。我怎样才能更改下面的代码?
def read_attribute_with_mapping(attr_name)
read_attribute_without_mapping(ADDRESS_MAPPING[attr_name] || attr_name)
end
alias_method_chain :read_attribute, :mapping
prepend
基本上就像导入一个模块,但它以 "in front" 其他代码结束(因此模块可以调用 super
到 运行 它所在的代码前面)。
这是一个运行可行的例子,与您的情况很接近。
module MyModule
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
class Example
prepend MyModule
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
我直接在Example
上定义了read_attribute
,但它也可以是从超类(例如ActiveRecord::Base
)继承的方法。
这是一个使用匿名模块的更短但更神秘的版本:
class Example
prepend(Module.new do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end)
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
更新:
只是为了好玩和解决下面的问题,下面是如何在不必自己明确制作任何模块的情况下完成的。我不认为我会选择自己这样做,因为它掩盖了一个共同的模式。
# You'd do this once somewhere, e.g. config/initializers/prepend_block.rb in a Rails app.
class Module
def prepend_block(&block)
prepend Module.new.tap { |m| m.module_eval(&block) }
end
end
# Now you can do:
class Example
prepend_block do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo