2012-11-06 8 views
8

Ruby'de bir sınıfın bir dizi modül içermesini ve bu modülleri başlatırken bir bloğu veya yöntemi (veya yalnızca bir örnek değişkenini düzenlemenin bir yolunu bulmayı) bulmasını istiyorum. sınıf. Bunu modülde bir yöntem oluşturarak ve daha sonra 'initialize method' olarak çağırarak yapabileceğimi biliyorum, ancak bunu modülün dahil edilmesi ve modülleri eklemek için eklediğiniz herhangi bir kodu yürütmek için bir yöntem çağırmak suretiyle bunu yapmanın bir yolunu istiyorum Bu şekilde, her bir modülün dahil edildiği başlangıç ​​modülünde bir kod satırı eklemekten endişe etmeden bir sınıfa dahil olan çok miktarda şey alabilirim.Ruby: Modül aracılığıyla yöntemi başlatmak için şeyler ekleme

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] 

Bu biraz ağız çekebilir: Ben aliasing, süper ve ilgili şeyleri teslim ettik ama burada başarmak umuyorum anlamak yardımcı olursa ... şey almadım bazı pseudocode var ama bence başlık, yapmaya çalıştığım şeyi özetliyor. Herhangi bir yardım için teşekkürler!

cevap

7

Bunu yapmanın birkaç yolu vardır. Bu örnek initialize yöntemi yeniden tanımlamak ve istediğiniz ne olursa olsun ek kod katacak:

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 

Ancak: Ben gerçekten bulmak istediğiniz sınıflara olduğunu düşünüyorum. Benzer davranışa sahip çok fazla sınıfınız varsa, yaptığınız gibi, doğal soyut bir ebeveyn sınıfının olup olmadığını kendinize sorun. super ile neler yaptığınızı ve neden çalışmadığını açıklayabilir misiniz?

+0

Haklısınız, süper nasıl çalıştığına baktım ve hangi modül ya da hangi modül olursa olsun eklenen herhangi bir sayıda modül için kod çalıştırabiliyorum. Temel olarak modüller için bir üst zincirler zinciri oluşturdu: – thIIIrd

+0

Bu kadar para, teşekkürler. Rails CanCan yetkilendirme deseni için 'ability.rb' dosyalarını ayırmak için bunu kullandım: http://stackoverflow.com/a/25723811/293280 –