![](/img/trans.png)
[英]Rails - alias_method_chain with a 'attribute=' method
[英]Rails 3: alias_method_chain still used?
不,它已被模塊中方法重寫和super
關鍵字的巧妙使用所取代。
基本上,您可以在包含的模塊中定義原始功能,然后在另一個包含的模塊中覆蓋它。 當您在覆蓋函數中調用super
時,它將調用原始函數。 但是有一個陷阱。 您必須在包含基礎模塊之后並按照您希望鏈接發生的順序來包含擴展模塊。
class Something
module Base
def my_method
# (A) original functionality
end
end
module PreExtension
def my_method
# (B) before the original
super # calls whatever was my_method before this definition was made
end
end
module PostExtension
def my_method
super # calls whatever was my_method before this definition was made
# (C) after the original
end
end
include Base # this is needed to place the base methods in the inheritance stack
include PreExtension # this will override the original my_method
include PostExtension # this will override my_method defined in PreExtension
end
s = Something.new
s.my_method
#=> this is a twice extended method call that will execute code in this order:
#=> (B) before the original
#=> (A) the original
#=> (C) after the original
Railscasts的 Ryan Bates討論了如何在Rails路由代碼中使用它 。 我建議您觀看它以及他的其他截屏視頻。 他們有權將編織的祖母轉變為Rails大師。
PS: 感謝Peeja糾正我的原始答案中的一個基本錯誤。 謝謝。
通常,模塊永遠不能覆蓋其包含的類中的方法。這是因為模塊包含的工作就像子類化。 一個超類也不能覆蓋其子類的方法,也不會期望它。
當模塊包含在類中時,該模塊將在該類的祖先鏈中緊隨該類之后插入。 從類中調用super
將調用模塊的實現。
class Something
module PreExtension; end
module PostExtension; end
include PreExtension
include PostExtension
end
Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
每當在Something
上調用方法時,Ruby都會按順序瀏覽此列表並調用找到的第一個實現。 如果實現調用super
,它將繼續查找並找到下一個。
這意味着后面包含的模塊優先於前面包含的模塊,並且可以調用super
獲得早期模塊的實現。 這是因為將包含的模塊直接在類之后插入到祖先鏈中。 這是Edgerunner提到的路由代碼的工作方式。 該代碼將所有內容放入模塊,如下所示:
class SomethingNew
module Base
def my_method
puts "(A)"
end
end
module Extension
def my_method
puts "(B)"
super
end
end
include Base
include Extension
end
SomethingNew.new.my_method
# Output:
# >> (B)
# >> (A)
SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
這就是為什么alias_method_chain
首先存在的原因。 如果不能將基本代碼放入模塊中,則不確定如何完成等效的alias_method_chain
。
我看到在Rails 3.0.0中不再存在alias_method_chain
。 http://api.rubyonrails.org/不報告它,而rails console
報告它是undefined local variable or method
。
另請參見-https: //rails.lighthouseapp.com/projects/8994/tickets/285-alias_method_chain-limits-extensibility#ticket-285-20
更新:正如@ecoologic在評論中指出的那樣,Rails 3.1.1中仍然存在alias_method_chain
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.