ruby混合和遗传注射
发布时间:2020-12-17 07:08:35 所属栏目:百科 来源:网络整理
导读:我需要在Parent类的每个子类中注入一个回调.因此,必须先调用带回调的方法,然后调用所有存在的链: 有可能实现alias_method(或alias_method_chain): module ChildMod1 def save puts "save ChildMod1" super endendmodule ChildMod2 def save puts "save Chi
我需要在Parent类的每个子类中注入一个回调.因此,必须先调用带回调的方法,然后调用所有存在的链:
有可能实现alias_method(或alias_method_chain): module ChildMod1 def save puts "save ChildMod1" super end end module ChildMod2 def save puts "save ChildMod2" super end end class Parent def save puts "save Parent" end end class Child < Parent include ChildMod1 include ChildMod2 def save puts "save Child" super end alias_method :old_save,:save module_eval <<-R def save puts "save Callback" old_save end R end c = Child.new c.save 产量 save Callback save Child save ChildMod2 save ChildMod1 save Parent 但是有可能通过继承实现这一目标吗?比如ChildMod1或ChildMod2.我想在模块空间中执行代码以从继承中获得所有好处 module ChildMod1 def save puts "save ChildMod1" super end end module ChildMod2 def save puts "save ChildMod2" super end end class Parent def save puts "save Parent" end end class Child < Parent include ChildMod1 include ChildMod2 def save puts "save Child" super end module_eval <<-R def save puts "save Callback" super end R end c = Child.new c.save 产量 save Callback save ChildMod2 save ChildMod1 save Parent 如你所见,它只是覆盖了Child UPDATE class TestEval def redefine_me puts "Test method" super # I expect that it will call Eval method,but module_eval just overwrite it end module_eval <<-R def redefine_me puts "Eval method" end R end UPDATE2 class TestEval def initialize class << self def redefine_me puts "Eval method" super end end end def redefine_me puts "Test method" end end TestEval.new.redefine_me 假设我有一个类方法“field”,它将一些实例方法添加到Datastream中(前者它将添加setter和getter方法)并且我想重新定义其中一个方法,如下所示: class Datastream field :name def name=(value) puts "redefined!" super end end 解决方法
您可以将回调方法放在其自己的模块中,并重写Parent的initialize方法以扩展该模块(如果需要,使用alias_method).这将把回调方法放在Child的方法之前,将它链接到每个Child实例的单例类.只需从第二个代码示例中删除module_eval部分,然后在c = Child.new之前添加:
module Callback def save puts "save Callback" super end end class Parent alias_method :old_initialize,:initialize def initialize old_initialize extend Callback end end 输出: save Callback save Child save ChildMod2 save ChildMod1 save Parent (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |