簡體   English   中英

如何為已棄用的 alias_method_chain 重構代碼

[英]How to refactor code for deprecated alias_method_chain

我正在升級我的 rails 應用程序,我收到一條警告說alias_method_chain is deprecated. Please, use Module#prepend instead 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基本上就像導入一個模塊,但它最終“在”其他代碼的“前面”(因此模塊可以調用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM