2017-03-28 16 views
1

個々のモジュールに対してincludedコールバックを定義できることはわかっています。モジュールが含まれている場合のRubyコールバック

モジュールが別のモジュールまたはクラスに含まれている場合に呼び出されるコールバックを定義する方法はありますか?コールバックは、好ましくは、含まれるモジュールと、それが含まれるクラス/モジュールの両方へのアクセスを有する。

+0

コールバックはあなたが望むものですが、私はあなたの混乱が何であるか分かりません – Tsao

+0

@Tsao、それはカットアンドドライされていません。もし 'クラス' Cがモジュール 'M'を含んでいて、' M'が 'include'を使って別のクラス' D'( 'D.include(M) ')に' M'を含めると、 'M''のコールバック'インクルード ' 2回目は「D」に、3回目は「M」を含むようになります。 –

答えて

3

私はRubyで組み込みの方法を考えることはできません。

代わりに、コールバックを作成するためにModuleクラスを直接サンクパッチすることもできます。これを行うために、元のメソッドincludeextendにいくつかのラッパーメソッドを追加して、includeまたはextendメソッドが呼び出されるたびに定義されたコールバックの実行を強制することができます。次の行に沿って

何かが動作するはず:

class Module 

    def self.before 
    m_include = instance_method(:include) 
    m_extend = instance_method(:extend) 

    define_method(:include) do |*args, &block| 
     included_callback(args[0]) 
     m_include.bind(self).call(*args, &block) 
    end 

    define_method(:extend) do |*args, &block| 
     extend_callback(args[0]) 
     m_extend.bind(self).call(*args, &block) 
    end 
    end 

    def included_callback(mod_name) 
    puts "#{self} now has included Module #{mod_name}" 
    end 

    def extend_callback(mod_name) 
    puts "#{self} now has extended Module #{mod_name}" 
    end 

    before 
end 

例を、それが動作することをテストする:

> TestIncludeAwesome now has included Module Awesome 
> TestExtendAwesome now has extended Module Awesome 
+0

ありがとう!これは私が欲しいもののように見えます。 – user3712482

+0

いいえ心配..:)!!!私のソリューションがあなたの問題を解決した場合、それを受け入れられるとマークすることができますか? – Aegis

0

module Awesome 

    def bar 
    puts "bar" 
    end 

    def self.baz 
    puts "baz" 
    end 
end 

class TestIncludeAwesome 
    include Awesome 
end 

class TestExtendAwesome 
    extend Awesome 
end 

コード例は、次の出力として印刷すべきです

class D 
    def self.callback(mod) 
    include mod 
    end 
end 

module M 
    def hello 
    puts 'hi' 
    end 

    def self.included(klass) 
    D.callback(self) unless klass == D 
    end 
end 

class C 
    include M 
end 

C.new.hello #=> 'hi' 
D.new.hello #=> 'hi' 

Whe n CMを含み、M::includedklass#=>Cで実行されます。 klass == Dfalseであるので、D.callback(M)が実行されます。 callbackは、をクラスDに含めると、M::includedklass#=>Dで実行されます。 klass == Dが真であるので、MDに2度目に含まれません。

関連する問題