2012-11-06 63 views
8

在Ruby中,我希望有一个类包含一系列模块,并使这些单独的模块在初始化时执行块或方法(或只是找到某种方式来编辑实例变量)类。我知道我可以通过在模块中创建一个方法然后在类的initialize方法中调用它,但我想通过简单地包含模块并调用一个方法来执行模块添加到初始化的任何代码这样我就可以在类中包含大量的东西,而不用担心在包含每个模块的初始化方法中添加一行代码。我已经签出走样,超级,以及相关的东西,但如果它有助于了解什么,我希望能在这里完成还没有得到任何东西......是一些伪代码:Ruby:通过模块添加东西来初始化方法

module Mod1 
    call_this_block_on_initialize { @a.push 4 } 
end 

module Mod2 
    call_this_block_on_initialize { @a.push 5 } 
end 

class Test 
    attr_accessor :a 
    include Mod1 
    include Mod2 

    def initialize 
     @a = [1, 2, 3] 
     call_those_blocks_set_by_mods 
    end 
end 

t = Test.new 
t.a # returns [1, 2, 3, 4, 5] 

这可能是有点罗嗦但我认为标题总结了我想要做的事情。谢谢你的帮助!

回答

7

有几种方法可以做到这一点。这个例子将重新初始化方法,并添加你想要的任何额外的代码:

module MyModule 
    def self.included(base) # built-in Ruby hook for modules 
    base.class_eval do  
     original_method = instance_method(:initialize) 
     define_method(:initialize) do |*args, &block| 
     original_method.bind(self).call(*args, &block) 
     @a.push 4 # (your module code here) 
     end 
    end 
    end 
end 

class Test 
    attr_accessor :a 

    def initialize 
    @a = [1, 2, 3]  
    end 

    # It must be included after the `initialize` 
    # definition or the module won't find the method: 
    include MyModule 
end 

然而: 我想你真正想要的是子类。如果你有很多类似行为的类,就像你看起来那样,问自己是否有一个自然的抽象父类。你能解释一下你用super做了什么,为什么它不起作用?

+0

你是对的,我研究了super的工作方式,并且我能够为任意数量的模块添加代码,无论组合或模块是什么。基本上为模块做了一个超级链: – thIIIrd

+0

这是钱,谢谢。我用它来分离Rails CanCan授权模式的'ability.rb'文件:http://stackoverflow.com/a/25723811/293280 –